0
votes

I'm writing a CLR wrapper for an unmanaged C++ library.

There are two files I'm including from the unmanaged lib:

//MyCLIWrapper.h
#include "C:\PATH\TO\UNMANAGED\Header.h"
#include "C:\PATH\TO\UNMANAGED\Body.cpp"

Then I'm writing CLI implementations for the unmanaged library functions:

//MyCLIWrapper.h
// includes ...
void MyCLIWrapper::ManagedFunction()
{
  UnmanagedFunction(); // this function is called successfuly
}

However, if my Unmanaged function contains calls to other functions that are defined in other unmanaged header files. This causes a compiler linkage error.

If I add includes to the unmanaged headers that define these functions, my errors get resolved. However, there is a lot of functions, and a lot of includes required.

Is there a different way to approach this?

EDIT: P.S. My managed code is in a separate Visual Studio project (output - DLL), and the compile settings are set to /CLR. Unmanaged code is in a separate Win32 project (output - DLL).

Also, after more research I concluded that theoretically I could set my Win32 unmanaged project to CLR and just add my managed classes and headers in there as an entry point, and then it would all compile into a single DLL file. That would probably solve (?) the linkage errors. However, I would prefer to preserve the loose coupling as well as the additional series of problems that can raise from setting my unmanaged project to CLR.

EDIT #2: The unmanaged class that I'm referencing (body.cpp, header.h) contains includes to the required files that define the functions that are causing the problems. However, my managed code doesn't pick up on the includes that are in the unmanaged body.cpp and header.h.

2
So unmanaged functions that don't call other unmanaged functions work fine? I've done something similar to what you're doing before, but I don't remember having that particular problem. What Visual Studio project settings have you changed to get things working so far? - Adam Goodwin
Having managed code and C++/CLI isn't changing anything here. The One Definition Rule is exactly the same as it would be for a project with only your native functions. - Ben Voigt
@BenVoigt I have edited my question: it's two separate projects, and unmanaged classes have all the definitions and includes, but my managed project doesn't pick up on these additional includes in the unmanaged classes. - Arman Bimatov

2 Answers

6
votes

Linker errors are a different kettle of fish from compiler errors. You forgot to document the exact linker errors you see, but a very common mishap when you compile code with /clr in effect is that the default calling convention for non-C++ member function changes. The default is __clrcall, a convention that's optimized for managed code. While functions compiled without /clr defaults to __cdecl. Which changes the way the function name is mangled. You see this back in the linker error message, is shows that it is looking for a __clrcall function and can't find it.

You'll need to either explicitly declare your functions in the .h file with __cdecl. Or tell the compiler that these functions are not managed code. Which is the best way to tackle it:

#pragma managed(push, off)
#include "unmanagedHeader.h"
#pragma managed(pop)
1
votes

Solution was fairly simple:

  1. I added both unmanaged and managed projects to a single solution in Visual Studio.
  2. Set the unmanaged project's "Configuration Type" to "Static Library" (.lib).
  3. Right click on the managed project -> References -> Add Reference -> Projects -> -> Add Reference.
  4. Then in my managed class, I include the header.h (only) just like I did in my question.
  5. Compiled successfully!

Thank you