2

I have a project in which I need to make a Visual C++ wrapper for a native C++ SDK, so that it can eventually be used in C#.

The SDK consists of .h files that I am correctly including (no compilation errors with these) and some .lib files which need to be referenced. And that seems to be the tricky part.

As I explained in this question, I get errors whenever I try to call a function that's part of the library. The errors look like this:

error LNK2080: unresolved token (0A000027) "public: static class vhtIOConn *__clrcall vhtIOConn::getDefault(enum vhtICRConn::DeviceType)"
error LNK2019: unresolved external symbol "public: static class vhtIOConn * __clrcall vhtIOConn::getDefault(enum vhtIOConn::DeviceType)"

As I understand, C++/CLR expects __clrdecl while native C++ offers __clrcall.

What is the proper way to go about this? I have read in many places that this is possible, but I haven't seen any practical working examples. Note that I am using Visual Studio 2010.

Community
  • 1
  • 1
Lee White
  • 3,649
  • 8
  • 37
  • 62
  • Wow. I'm always amazed how superfluously overcomplicated yet broken Windows' ABI is. +1 because it must be a pain to get something like this working. –  Apr 02 '13 at 10:17
  • It is quite a pain indeed. I try to use this website as a last resort, but right now I simply don't have the slightest clue as to how to continue. – Lee White Apr 02 '13 at 10:28
  • Unfortunately I can't really help you as - fortunately - I've never done Windows programming, but there are people around here who will have the answer for sure. –  Apr 02 '13 at 10:29
  • Why are you creating a Visual C++ wrapper when the wrapper itself could be written in C# by using PInvoke? As for the calling convention pick the one that applies to your code. – Security Hound Apr 02 '13 at 12:21

1 Answers1

1

You can tell what's going wrong from the linker error, note the __clrcall in the error message. That indicates that the compiler thinks that your native C++ is being compiled to MSIL, not to native code. Which compiles just fine, any compliant C++03 code can be compiled to MSIL but dies when you try to link it. You have to let it know, you can simply do so with a #pragma:

#pragma managed(push, off)
#   include "foo.h"
#pragma managed(pop)
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Could you maybe elaborate a bit further? In my example, I have a `MainForm.h` file, which includes a couple of Unmanaged C++ files. Let's just call those files `foo.h`. If I use the code that you posted, it gives a lot of `__clrcall cannot be used on functions compiled to native code` errors, which makes me think it still treats `foo.h` as CLR code. I thought changing `managed` to `unmanaged` would help, but then it adds: `cannot compile unmanaged function with /clr:pure or /clr:safe` to all those instances. – Lee White Apr 02 '13 at 13:01
  • 1
    There is nothing pure or safe about your code, you will need to compile with plain /clr. – Hans Passant Apr 02 '13 at 13:07
  • I tried that and it worked. Thanks a lot! Now I'm puzzled as to why [this](http://msmvps.com/blogs/vandooren/archive/2008/09/03/extending-a-native-c-project-with-managed-code.aspx) website offers such a complicated solution... :) – Lee White Apr 02 '13 at 13:26