使用dll将C#StringBuilder / String传递给C char*
Passing C# StringBuilder / string to C++ char* using DLL
我一直在将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);
}
它可以正常工作并连接到本地服务器。
因此,用于检查我添加了您可以在上面DLL标头代码中看到的Copystr,并且应该获取Mysock对象的IP地址并将其写入C#TextBox。
。,如果确实有一个硬编码的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 Call的持续时间内有效。
的确,即使您仅在C 中使用此课程,它的设计也是不可行的。您的班级需要拿起字符串的副本,而不是指针的副本。
该解决方案是您的C 代码专门使用std::string
。让该课程照顾记忆管理和复制。仅在P/Indoke Interop边界处使用C字符串。
将ipAddress
更改为类型std::string
,并使构造函数看起来像:
mySock::mySock(const std::string inIP, const int inPort)
{
ipAddress = inIP;
port = inPort;
}
您仍然需要在Interop包装器函数中使用C字符串,但这可以利用从const char*
到std::string
的隐式转换。
mySock* mySock_Create(const char* IP, const int prt)
{
return new mySock(IP, prt);
}
就P/Invoke而言,您滥用StringBuilder
和char*
。当您分配了由Callee修改的呼叫者缓冲区时,它们是配对的。对于传递到C 代码的字符串,请使用string
和const char*
。
[DllImport("...", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr mySock_Create(string IP, int prt);
- 使用char类型将decimal转换为string,将string转换为decimal
- std::string 构造函数如何处理固定大小的 char[]?
- C++:将模板类型 char 转换为 std::string
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- "No suitable conversion function from 'std::string' to 'const char *' exists"
- 将"std::string {aka std::basic_string}"赋值中的不兼容类型<char>
- 错误:为"运算符 std::string {aka std::__cxx11::basic_string}"指定的返回类型<char>
- 为什么std::string没有(显式)const char*强制转换
- 将 std::string 转换为 const char* 用于 printf 消耗
- 我可以使用istream_iterator将<char>一些 istream 内容复制到 std::string 中吗?
- 让 'std::vector<unsigned char>' 从 'std::string' 中窃取内存
- 错误:请求从"Mstream"转换为非标量类型"std::string {aka std::basic_string<char>}"
- C :如何使用char / string 2D数组接受用户的1个以上的源性
- 我们应该在带有 char *func(char *string) 的函数中返回什么?需要简要说明这与 c 中的 char
- C++ 从 char* 到 char 的转换无效 (char* = *string.begin() )
- 无法在循环中读取Char/string
- 当我将char* string赋值给std::string时,可以释放它的内存吗?
- C char string和stint .h uint8_t在嵌入式系统中的兼容性
- 如何在c++中将LPBYTE转换为char */string
- 如何在等待用户输入int, float或其他类型时拒绝输入char/string