Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a c dll from C++, C# and ruby

Tags:

c++

c#

ruby

Hi I have a DLL with a function that I need to call. The signature is:

const char* callMethod(const char* key, const char* inParams);

If I use ruby everything works fine:

attach_function :callMethod, [:string, :string], :string

If I use C++ or C# I get stack overflow!?

C#:

[DllImport("DeviceHub.dll", CallingConvention = CallingConvention.Cdecl)]
private unsafe static extern IntPtr callMethod(
    [MarshalAs(UnmanagedType.LPArray)] byte[]  key,
    [MarshalAs(UnmanagedType.LPArray)] byte[] inParams
);

System.Text.UTF8Encoding encoding = new UTF8Encoding();
IntPtr p = callMethod(encoding.GetBytes(key), encoding.GetBytes(args)); // <- stack overflow here

c++:

extern "C"
{
typedef  DllImport const char*  (  *pICFUNC) (const char*, const char*); 
}
HINSTANCE hGetProcIDDLL = LoadLibrary(TEXT("C:\\JOAO\\Temp\\testedll\\Debug\\DeviceHub.dll"));  
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE (hGetProcIDDLL),"callMethod");*      pICFUNC callMethod;
callMethod = (pICFUNC) lpfnGetProcessID;
const char * ptr = callMethod("c", "{}");

I have tried lots of variations for function calling : WINAPI, PASCAL, stdcall, fastcall,... nothing works.

The DLL has not been made by me and I have no control on it.

Can anyone help me with any suggestion!?

like image 707
Joao Avatar asked May 03 '12 17:05

Joao


People also ask

Can you call C# code from C++?

C++/CLI can call any C# function as if it were a "regular" C++ function.


2 Answers

Make sure that the declaration in your header is enclosed in an extern "C" block:

extern "C" {

const char* callMethod(const char* key, const char* inParams);

}

See http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3

like image 144
Gort the Robot Avatar answered Oct 19 '22 12:10

Gort the Robot


This is just a idea but AFAIK this might be a issue with null-terminated strings, const char* myvar is null-terminated but a byte array isn't. Everything you need to to is to change the call to ...(String a, String b) and marshal them as LPStr.

like image 22
Felix K. Avatar answered Oct 19 '22 11:10

Felix K.