如何将此字符数组参数从 C 编组为 C# 中的字符串?
How can I marshal this character array parameter from C to a string in C#?
我有以下函数,作为另一个 class 的一部分写在 C:
int example(char *remoteServerName)
{
if (doSomething(job))
return getError(job);
if (job->server != NULL) {
int length = strlen(jobPtr->server->name); // name is a char * of length 1025
remoteServerName = malloc (length * sizeof(char));
strncpy(remoteServerName, jobPtr->server->name, length);
}
return 0;
}
如何从中取回 remoteServerName
?我尝试了以下方法:
[DllImport("example.dll")]
public static extern int example(StringBuilder remoteServerName);
var x = new StringBuilder();
example(x);
Console.WriteLine(x.ToString());
但字符串始终为空。
您需要为要返回的字符串分配一些 space。而不是:
var x = new StringBuilder();
提供容量值:
var x = new StringBuilder(1024);
您还应该删除对 malloc
的呼叫。调用者分配内存。这就是用 StringBuilder
.
编组的目的
您没有正确使用 strncpy
,因此未能编写空终止符。您可以像这样传递缓冲区长度:
int example(char *remoteServerName)
{
if (doSomething(job))
return getError(job);
if (job->server != NULL) {
// note that new StringBuilder(N) means a buffer of length N+1 is marshaled
strncpy(remoteServerName, jobPtr->server->name, 1025);
}
return 0;
}
但这会有点浪费,因为隐含了所有的零填充。真的,strncpy
几乎没用,你应该使用不同的函数来复制,正如之前在这里多次讨论过的那样。我真的不想被卷入其中,因为它有点偏离问题。
明智的做法是将 API 设计为允许调用者也传递字符数组的长度,以便被调用者可以确保不会溢出缓冲区,这样你就不会需要像这里的代码一样使用魔法常量。
我有以下函数,作为另一个 class 的一部分写在 C:
int example(char *remoteServerName)
{
if (doSomething(job))
return getError(job);
if (job->server != NULL) {
int length = strlen(jobPtr->server->name); // name is a char * of length 1025
remoteServerName = malloc (length * sizeof(char));
strncpy(remoteServerName, jobPtr->server->name, length);
}
return 0;
}
如何从中取回 remoteServerName
?我尝试了以下方法:
[DllImport("example.dll")]
public static extern int example(StringBuilder remoteServerName);
var x = new StringBuilder();
example(x);
Console.WriteLine(x.ToString());
但字符串始终为空。
您需要为要返回的字符串分配一些 space。而不是:
var x = new StringBuilder();
提供容量值:
var x = new StringBuilder(1024);
您还应该删除对 malloc
的呼叫。调用者分配内存。这就是用 StringBuilder
.
您没有正确使用 strncpy
,因此未能编写空终止符。您可以像这样传递缓冲区长度:
int example(char *remoteServerName)
{
if (doSomething(job))
return getError(job);
if (job->server != NULL) {
// note that new StringBuilder(N) means a buffer of length N+1 is marshaled
strncpy(remoteServerName, jobPtr->server->name, 1025);
}
return 0;
}
但这会有点浪费,因为隐含了所有的零填充。真的,strncpy
几乎没用,你应该使用不同的函数来复制,正如之前在这里多次讨论过的那样。我真的不想被卷入其中,因为它有点偏离问题。
明智的做法是将 API 设计为允许调用者也传递字符数组的长度,以便被调用者可以确保不会溢出缓冲区,这样你就不会需要像这里的代码一样使用魔法常量。