[英]C# wrapper class for c++ lib dll
I am trying to create a class in c# to access the function in a c++ lib. 我试图在c#中创建一个类,以访问c ++库中的函数。 The function in the c++ dll :
C ++ dll中的函数:
bool WriteReply(const unsigned char *reply, const unsigned long reply_length)
. bool WriteReply(const unsigned char *reply, const unsigned long reply_length)
。
A sample of how its used in c++:- 在C ++中如何使用的示例:-
unsigned short msg_id = 0x0000;
byte msg_body[] = {(byte)(GetTickCount()/0x100)}; // a random value for loopback data
// combine the message id and message body into an big msg
unsigned long msg_length = sizeof(msg_id)+sizeof(msg_body);
byte* big_msg = new byte[msg_length];
big_msg[0] = LOBYTE(msg_id);
big_msg[1] = HIBYTE(msg_id);
memcpy((void*)&big_msg[2], (void*)msg_body, sizeof(msg_body));
// send the big message
if (!big_dev.WriteReply(big_msg, msg_length))
{
//do something here
}
I can't seem to pass the function from c# to the dll ( AccessViolationException
). 我似乎无法将函数从c#传递到dll(
AccessViolationException
)。 This is the command i've tried:- 这是我尝试过的命令:
byte[] bytearray = new byte[3] { 0x01, 0x02, 0x03 };
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytearray.Length);
Marshal.Copy(bytearray, 0, unmanagedPointer, bytearray.Length);
bool writestatus = (bool)NativeMethods.WriteReply(unmanagedPointer, (uint)bytearray.Length);
and on the import side:- 在进口方面:
[DllImport("dllname.dll", EntryPoint = "WriteReply")]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool WriteReply(IntPtr msg, uint reply_length);
Please let me know where have i gone wrong?Thanks! 请让我知道我在哪里出了问题?
Assuming your C++ method uses the string and does not modify it... 假设您的C ++方法使用字符串并且不修改它...
Try this 尝试这个
__declspec(dllexport) bool __cdecl WriteReply(const unsigned char *reply, const unsigned long reply_length);
[DllImport("libfile.dll", EntryPoint = "WriteReply")]
private static extern bool WriteReplyExternal(
[MarshalAs(UnmanagedType.LPStr)] [Out] string replyString,
[Out] UInt32 replyLength);
Or better yet (since C strings are null-terminated and the buffer is readonly, so you don't have to worry about buffer overflow, the length parameter is redudant): 或更好(由于C字符串以null终止并且缓冲区是只读的,因此您不必担心缓冲区溢出,length参数是多余的):
__declspec(dllexport) bool __cdecl WriteReply(const unsigned char *reply);
[DllImport("libfile.dll", EntryPoint = "WriteReply")]
private static extern bool WriteReplyExternal(
[MarshalAs(UnmanagedType.LPStr)] [Out] string replyString);
These will work if the method is not within a class, otherwise you will need to use the C++ mangled name as the entry point . 如果该方法不在类之内,则这些方法将起作用,否则,您将需要使用C ++杂乱的名称作为入口点 。
If your string contains characters outside the 1...127 ASCII range (eg non-English letters), you should use wchar_t instead of char in the C++ and LPWStr instead of LPStr in the marshalling. 如果您的字符串包含1 ... 127 ASCII范围之外的字符(例如,非英语字母),则应在编组中使用wchar_t代替char,在C ++中使用LPWStr代替LPStr。
Edit: 编辑:
You need to wrap the private method with another method with a signature that is more appropriate for .NET eg 您需要将私有方法与具有更适合于.NET的签名的其他方法包装在一起,例如
public void WriteReply(string message)
{
var result = WriteReplyExternal(message, message.Length);
if (result == false)
throw new ApplicationException("WriteReplay failed ...");
}
I think the latest addition of code provides a clue as to the real problem: 我认为最新添加的代码提供了有关实际问题的线索:
if (!big_dev.WriteReply(big_msg, msg_length))
This cannot work because WriteReply
is an member function. 由于
WriteReply
是成员函数,因此无法工作。 You need to be calling a C style function rather than a C++ member function. 您需要调用C样式函数而不是C ++成员函数。 The latter requires an instance (
big_dev
in the code sample). 后者需要一个实例(代码示例中的
big_dev
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.