2

I am attempting to create a CLI DLL to bridge between my unmanaged C++ executable project and another managed project, all in a single Visual Studio solution.

The problem I am having is earlier, though: I am unable to link reference the unmanaged C++ project in my new CLI project. I have included the required .h files, and added a reference to the unmanaged project in the CLI project. The compilation is successful, but I am getting linkage errors I have not seen before:

Error 2
error LNK2028: unresolved token (0A000088) "public: __cdecl ...

I have added a reference in the project properties and included the .h files.

Thanks

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
Gilad
  • 343
  • 1
  • 3
  • 13
  • you cannot 'reference' unmanaged dlls in the same way as managed ones. Instead, you have to add their corresponding .lib files as input to the linker – stijn Sep 19 '12 at 08:17

1 Answers1

2

Seems like the linker is missing some intermediate information on the other project. I truly don't remember if 'referencing' native projects does set up the linking phase automatically.. I actually find it strange you say "reference".. for me the word "reference" it a bit limited to the world of .Net assemblies because of the "add reference" in the VS, which makes noone care about includes/libraries and which IIRC is unavailable for native dlls for obvious reasons. If you meant you configured the linker options manually, then pardon me :)

If not - please explain how did you reference the native module.

Either way, if the "referencing" worked earlier, the file names might went out of sync if i.e. you renamed the project, of maybe file timestamps were a bit off and the VS did not notice new versions.. Simple Clear&Rebuild sometimes magically helps. If not, you can try to manually delete Debug/Release/Bin/Obj folders and try rebuilding again.

To try at diagnosing, the first step is to see what the linker is given as input: in the project property pages for the C++/CLI project, check Linker->CommandLine and see if a file with name similar to "myOtherNativeCppProjectName.lib" is visible there. If not - here's the problem, just add it in the linker options on previos linker pages, or re-do the reference-adding, then clean, rebuild and see what happens.

To say something more, you'd have to post whole error message - this one is truncated at function name, so it's hard to tell if it is your function, or some missing-library module. As the compilation phase succeeded and the problem is at link - are you 100% sure you have that function implemented? I mean, correct .h was surely provided to the C++/CLI project, but were the right .cpp files matching the .h file included in the native? That's quite common too to forget to add one file. Or forget to instantiate a template.. Or mistype class/function names between .H and .CPP..

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
  • The unmanaged C++ project is an executable, and therefore does not create a .lib file, so I cannot find a reference to a lib file anywhere. Is it possible to reference the obj files from the other project? – Gilad Sep 19 '12 at 08:06
  • No, .obj files are intermediate files that should not be used outside of the project build. They are temporaries, not final products. They might actually turn useful, as the .obj suggest a raw module like in static libraries, but leave that attempt as a last resort. .exe files can generate .lib files too, just as normal dll does - it is all matter of whether they do contain exportable symbols or not. Have you used `__declspec(dllexport)` at all in the code of your .exe? If not - then no symbols are exportable, and that's why the LIB is not generated - it's skipped when empty. – quetzalcoatl Sep 19 '12 at 08:14
  • So just so I'm clear: if I want to include functionality from my executable project I need to either compile it as a lib or use the __declspec(dllexport) on whatever functionality I require? – Gilad Sep 19 '12 at 08:16
  • You do not have to "compile it as lib". The .lib file is a side effect of building a .dll or .exe file. This file is a lis of all functions aka. "symbols" that this .dll or .exe makes available for others to use. You totally have to use __declspec(dllexport) on thing you want to publicize, or else every symbol will be made 'private' and hidden, or rather you may think of it as leaving it "unnamed" or optimized-out after compilation. __declspec(dllexport) pins the marked functions or classes as "must exist in this exact form" and "must be listed in .lib/.exp files". – quetzalcoatl Sep 19 '12 at 08:38
  • There's a ".dll+.lib" combo (or ".exe+.lib"). The ".dll+.lib" pair actually is the dynamic library ".dll" and a small helper/wrapper static library ".lib". The ".lib" files are always some kind of a static library. If you build project as a dynamic library, as DLL, you get a DLL and the small lib is a proxy/helper that rebounces all function calls to the actual DLL. You can also build as static library, as LIB - then only .lib is produced, and that .lib contains everything and there's no DLL file. So, if you want to keep it separate, **do not** "compile as LIB". – quetzalcoatl Sep 19 '12 at 08:48
  • Build as a lib only when you want to create a completely static library. Otherwise, build as application, or as dynamic library, and use the appropriate declspec on whatever names you want to make importable by others. – quetzalcoatl Sep 19 '12 at 08:50
  • Thanks :) I have exported using __declspec(dllexport) and it works. Kind of a bummer I don't have enough rep to add 1 to your answer :) – Gilad Sep 19 '12 at 08:55