简体   繁体   English

从C ++,C#和ruby调用c dll

[英]Calling a c dll from C++, C# and ruby

Hi I have a DLL with a function that I need to call. 嗨,我有一个DLL,我需要调用一个函数。 The signature is: 签名是:

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

If I use ruby everything works fine: 如果我使用ruby一切正常:

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

If I use C++ or C# I get stack overflow !? 如果我使用C ++或C#,我会得到堆栈溢出

C#: 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++: 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. 我尝试了很多函数调用的变体:WINAPI,PASCAL,stdcall,fastcall,......没什么用。

The DLL has not been made by me and I have no control on it. DLL并非由我制作,我无法控制它。

Can anyone help me with any suggestion!? 谁能帮我提出任何建议!?

Make sure that the declaration in your header is enclosed in an extern "C" block: 确保标题中的声明包含在extern“C”块中:

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 请参阅http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3

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. 这只是一个想法,但AFAIK这可能是一个以null结尾的字符串的问题, const char* myvar是以null结尾的,但是字节数组不是。 Everything you need to to is to change the call to ...(String a, String b) and marshal them as LPStr . 你需要做的就是将调用更改为...(String a, String b)并将它们编组为LPStr

I see no reason why you should not change your call to 我认为没有理由不改变你的电话

[DllImport("DeviceHub.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport(“DeviceHub.dll”,CallingConvention = CallingConvention.Cdecl)]
private unsafe static extern string callMethod( private unsafe static extern string callMethod(
string key, 字符串键,
string inParams 字符串inParams
); );

You need to send pointers, not actual values/bytes to the function. 您需要向函数发送指针,而不是实际值/字节。
I always use this mapping when generating the type conversion for native function calls. 在为本机函数调用生成类型转换时,我总是使用此映射
Same applies for the c++ code, you need create variables with the content and call the function then. 同样适用于c ++代码,您需要使用内容创建变量并调用该函数。

Stack Overflow Exception is an error put in microsoft languages to prevent infinite recursion, and to prevent incompatible programs from interacting with each other. Stack Overflow Exception是微软语言中的一个错误,用于防止无限递归,并防止不兼容的程序相互交互。 If your dll method uses recursion, try rewriting it with iteration. 如果您的dll方法使用递归,请尝试使用迭代重写它。 Otherwise, do as Ove said, and try with strings. 否则,像Ove所说,并尝试使用字符串。 If it still doesn't work, Google for a compatible type. 如果它仍然无法正常工作,Google会出现兼容类型。 That's all I can say without knowing the actual method. 在不知道实际方法的情况下,我可以说这一切。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM