2

I want to send my C# string to a C++ DLL function. I have succeeded, both with StringBuilder:

[C#]
public static extern int installHook(StringBuilder directory);
StringBuilder myText = new StringBuilder(512);
myfunc(myText);

[C++]
int OPENGLHOOK_API myfunc(char* directory)
{
    ::MessageBoxA(NULL,directory,"test123",0);
}

and with a simple string & wchar:

[C#]
public static extern int installHook(string directory);
myfunc("myText");

[C++]
int OPENGLHOOK_API installHook(wchar* directory)
{
    wstring s = directory;
    const wchar_t* wstr = s.c_str();
    size_t wlen = wcslen(wstr) + 1;
    char newchar[100];
    size_t convertedChars = 0;
    wcstombs_s(&convertedChars, newchar, wlen, wstr, _TRUNCATE);

    ::MessageBoxA(NULL,newchar,"test123",0);
}

as it was mentioned in other thread on StackOverflow. The problem is that everytime I do this, I get an error because the function signatures are not the same:

Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Users\Dave\Documents\Visual Studio 2010\Projects\OpenGLInjector\Loader\bin\Release\Loader.vshost.exe'. Additional Information: A call to PInvoke function 'Loader!Loader.Form1::myfunc' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

Any idea how I can fix my problem/what to do from here?

David Menard
  • 2,261
  • 3
  • 43
  • 67

2 Answers2

3

I believe the problem is the default calling convention between the two languages. C# is __stdcall and c++ is __cdecl, I believe. Try explicitly stating __stdcall on your C++ method signatures and see if that doesn't resolve the error.

C++:

int OPENGLHOOK_API __stdcall installHook(wchar* directory)

C#:

[DllImport( "yourdll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode )]
static extern int installHook(string directory);
Brandon Moretz
  • 7,512
  • 3
  • 33
  • 43
  • thanks, where exactly do I do this? do i replace the __declspec(dllexport)? - NVM got it, that works great, thanks – David Menard Jun 07 '11 at 19:46
  • Shouldn't the C++ be int __stdcall installHook(wchar* directory), i.e. without the OPENGLHOOK_API because OPENGLHOOK_API expands to __declspec(dllexport) ? – user1725145 Jun 28 '14 at 10:22
-1

You need to explicitly describe the unmanaged calling convention for 32bit, and in addition, you will need to explicitly describe the unmanaged string type- ASCII, UTF16, etc.

Puppy
  • 144,682
  • 38
  • 256
  • 465