views:

16

answers:

2

I have been working on getting a basic ATL project to compile in Visual Studio 2008 and I keep running into errors. Ultimately I have gotten stuck with the following build errors:

1>Linking...
1>   Creating library Debug\SomeProject.lib and object Debug\SomeProject.exp
1>dllmain.obj : error LNK2001: unresolved external symbol _LIBID_SomeProjectLib
1>SomeObject.obj : error LNK2001: unresolved external symbol _LIBID_SomeProjectLib
1>SomeObject.obj : error LNK2001: unresolved external symbol _IID_ISomeObject
1>Debug\SomeProject.dll : fatal error LNK1120: 2 unresolved externals

What am I overlooking or doing wrong? Here are the steps to reproduce.

  1. Create a new ATL Project named SomeProject. Accept all defaults.
  2. Right-click the project in the Solution Explorer and select Add > Class.
  3. Select ATL Simple Object and enter SomeObject as its Short Name. Accept all other defaults.

At this points the project builds fine. However I want to split my IDL among multiple files for better organization (my IDL would be thousands of lines long).

  1. Right-click the project and select Add > New Item.
  2. Select Midl File and enter ISomeObject as its filename.
  3. Open SomeProject.idl and cut the ISomeObject interface declaration. Replace it with import "ISomeObject.idl";.
  4. Paste the interface declaration in ISomeObject.idl.

In order to satisfy Microsoft's IDL compiler we need to change some options:

  1. Right-click the project and open its Properties. Go to the MIDL > Output section and enter the following values:
    • Header File: $(InputName).h
    • IID File: $(InputName)_i.cpp
    • Proxy File: $(InputName)_p.cpp
    • Generate Type Library: No
  2. Go to the C/C++ > Precompiled Headers section and set Create/Use Precompiled Header to Not using Precompiled Header. There are errors later if precompiled headers are used.
  3. Select the SomeProject.idl file so that its properties are displayed. Go to the MIDL > Output section and set Generate Type Library to Yes.
  4. Remove SomeProject_i.h and SomeProject_i.c from the Generated Files filter.
  5. Add the following Existing Items to the Generated Files filter. You may need to attempt to compile the project first.
    • SomeProject.h
    • SomeProject_i.cpp
    • ISomeObject.h
    • ISomeObject_i.cpp

Now, at this point I would expect the project to compile. But it doesn't. You should get the LNK1120 errors that I listed at the top of this question.

Any ideas? Am I overlooking something simple?

+1  A: 

Open a VS 2008 command prompt and go to the intermediate/output directory and look at someproject_i.obj. Try something like this:

dumpbin someproject_i.obj /symbols | find "LIBID"

If there's no libid defined in the object file, that's the problem. Perhaps it has the wrong name somehow? If there is one with the correct name, then the problem is that the linker isn't using it.

David Gladfelter
This is a good diagnosis tool, thank you for the tip.
emddudley
+1  A: 

Not sure what you are doing, or why you are doing this, but somewhere along the way you lost the blah_i.c source code file that midl.exe generates. It contains the GUIDs of the interfaces, coclasses and type library, the ones that the linker is complaining about. If you can't find it back, search for MIDL_DEFINE_GUID in the *.c files.

Edit: I see the problem now, you renamed the blah_i.c to blah_i.cpp. That's wrong, the file contains C declarations. The compiler mangles the identifiers differently when it is compiled as C++ code. Rename it back to .c. Or use the /Tc compile option.

Hans Passant
I am just trying to set up a simple ATL project. The only real change I'm making is moving the interface definition into its own IDL file. The IID files are being generated and included just fine. See the last step I took in setting up the project.
emddudley
@emd: post updated.
Hans Passant
OMFG... name mangling... how insidious. I was under the impression that compiling under C++ was supported due to all the #ifdef __cplusplus in the generated files.
emddudley