我有以下函数,作为 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());
但字符串始终为空。
最佳答案
您需要为要返回的字符串分配一些空间。而不是:
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 以允许调用者也传递字符数组的长度,以便被调用者可以确保不会溢出缓冲区,这样您就不需要使用魔法常量作为这里的代码可以。
关于c# - 如何将此字符数组参数从 C 编码为 C# 中的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42929576/