C# wrapper class for c++ lib dll
本文关键字:lib dll c++ for wrapper class | 更新日期: 2023-09-27 18:32:36
>我正在尝试在 c# 中创建一个类来访问 c++ 库中的函数。c++ dll 中的函数:
bool WriteReply(const unsigned char *reply, const unsigned long reply_length)
.
如何在 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
}
我似乎无法将函数从 c# 传递到 dll ( AccessViolationException
)。这是我尝试过的命令:-
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);
在进口方面:-
[DllImport("dllname.dll", EntryPoint = "WriteReply")]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool WriteReply(IntPtr msg, uint reply_length);
请让我知道我哪里出错了?谢谢!
假设您的C++方法使用该字符串并且不对其进行修改...
试试这个
__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);
或者更好(因为 C 字符串以 null 结尾并且缓冲区是只读的,所以您不必担心缓冲区溢出,长度参数是多余的):
__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);
如果该方法不在类中,则这些方法将起作用,否则需要使用C++损坏的名称作为入口点。
如果字符串包含 1...127 ASCII 范围之外的字符(例如非英语字母),则应在C++中使用 wchar_t 而不是 char,在编组中应使用 LPWStr 而不是 LPStr。
编辑:
您需要将私有方法与另一个具有更适合 .NET 的签名的方法包装,例如
public void WriteReply(string message)
{
var result = WriteReplyExternal(message, message.Length);
if (result == false)
throw new ApplicationException("WriteReplay failed ...");
}
我认为最新添加的代码提供了有关真正问题的线索:
if (!big_dev.WriteReply(big_msg, msg_length))
这不起作用,因为WriteReply
是成员函数。您需要调用 C 样式函数而不是 C++ 成员函数。后者需要一个实例(big_dev
在代码示例中)。