gpt4 book ai didi

c# - 使用 DLL 将 C# StringBuilder/string 传递给 C++ char*

转载 作者:太空宇宙 更新时间:2023-11-04 13:07:57 26 4
gpt4 key购买 nike

我一直在混合使用 C# GUI 和 C++ 代码来处理套接字连接。问题是将字符串传递给 C++ char* DLL 会导致它更改其在 C++ 类中的值(?)。

我有一个用于处理套接字的类,它做了一些改动以查找错误原因和一些让我进入类本身的函数:

extern "C" { __declspec(dllexport)

class mySock
{

int port;
SOCKET littleSock;

public:
char* ipAddress;
mySock() {};
mySock(char* inIP, int inPort);
~mySock();
int initialize();
int sendMsg(char* Msg);
//int addition(int a, int b);

};
}

extern "C" { __declspec(dllexport) mySock* mySock_Create(char* IP, int prt);}
extern "C" { __declspec(dllexport) mySock* mySock_Create1(); }
extern "C" { __declspec(dllexport) int mySock_initialize(mySock* inSocket); }
extern "C" { __declspec(dllexport) int mySock_sendMsg(mySock* inSocket,char* Msg); }
extern "C" { __declspec(dllexport) void mySock_delete(mySock* inSocket); }
extern "C" { __declspec(dllexport) void CopyStr(char* str1, mySock* inSocket)
{
strcpy_s(str1, strlen(str1), inSocket->ipAddress);
};
}

问题出现在使用 mySock_Create 的某处。

基本上是:

mySock* mySock_Create(char* IP, int prt)
{
return new mySock(IP, prt);
}

调用构造函数:

mySock::mySock(char* inIP, int inPort)
{
ipAddress = inIP;
port = inPort;
}

稍后ipAddress与inet_addr一起使用,连接到远程服务器。无论如何,上面的代码不允许我连接到服务器,但如果我只是像这样硬编码 IP 地址:

mySock* mySock_Create(char* IP, int prt)
{
return new mySock("192.168.1.164", prt);
}

它工作正常并连接到本地服务器。

因此为了检查,我添加了 CopyStr,您可以在上面的 DLL header 代码中看到它,它应该获取 mySock 对象的 IP 地址并将其写入 C# 文本框。

如果是硬编码的 IP 地址,它确实会显示该 IP 地址,但如果从 C# 传递 IP 地址,它只会返回一个未填充的矩形符号,我什至无法将其粘贴到此处。

这是链接和使用 DLL 的 C# 代码:

[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr mySock_Create(StringBuilder IP, int prt);
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int mySock_initialize(IntPtr value);
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int mySock_sendMsg(IntPtr value, string Msg);
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void mySock_delete(IntPtr value);
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr mySock_Create1();
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void CopyStr(StringBuilder str1, IntPtr value);

private void button3_Click(object sender, EventArgs e)
{
StringBuilder str = new StringBuilder("192.168.1.164", 50);
IntPtr we = mySock_Create(str, 16999);
StringBuilder str2 = new StringBuilder("255.255.255.255", 25);
CopyStr(str2, we);
textBox1.Text = str2.ToString();
if (mySock_initialize(we) == -2)
button3.Text = "Ups";

mySock_delete(we);
}

我也尝试过使用字符串代替 StringBuilder 或在导入选项中添加 CharSet=CharSet.Ansi。

我已经阅读了很多关于在这种情况下将字符串传递给 char* 的问题和解决方案,但我无法弄清楚为什么 ipAddress 的值不是'正确通过或在其他地方更改。

希望我把问题说得足够清楚,因为在与上面的代码打架后我已经很不合逻辑了。

最佳答案

主要问题出在您的 C++ 构造函数中:

mySock::mySock(char* inIP, int inPort)
{
ipAddress = inIP;
port = inPort;
}

这里你复制了一个指向字符数组的指针。这要求只要您需要使用 ipAddress,此指针就保持有效。从 C# 编码的字符串仅在 p/invoke 调用期间有效。

的确,即使您仅在 C++ 中使用此类,它的设计也是行不通的。您的类需要获取字符串的拷贝而不是指针的拷贝。

解决方案是让您的 C++ 代码独占使用 std::string。让那个类负责内存管理和复制。仅在 p/invoke 互操作边界使用 C 字符串。

ipAddress 更改为 std::string 类型,并使构造函数如下所示:

mySock::mySock(const std::string inIP, const int inPort)
{
ipAddress = inIP;
port = inPort;
}

您仍然需要在互操作包装函数中使用 C 字符串,但这可以利用从 const char*std::string 的隐式转换。

mySock* mySock_Create(const char* IP, const int prt)
{
return new mySock(IP, prt);
}

就 p/invoke 而言,您滥用了 StringBuilderchar*。当您有一个由调用者修改的调用者分配的缓冲区时,它们会配对。对于传递到 C++ 代码的字符串,请使用 stringconst char*

[DllImport("...", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr mySock_Create(string IP, int prt);

关于c# - 使用 DLL 将 C# StringBuilder/string 传递给 C++ char*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41371212/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com