c# - 如何将此字符数组参数从 C 编码为 C# 中的字符串?

标签 c# .net c pinvoke marshalling

我有以下函数,作为 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/

相关文章:

c# - 从多个 aspx 网页将数据插入 SQL 数据库表

.net - MSBuild WebFileSystemPublish步骤未在生成服务器上运行

c# - 更好的 PropertyChanged 和 PropertyChanging 事件处理

c - 在C中应用单向链表

c - 从 C 中的函数返回一个字符串

javascript - 如何使用 js-ctypes Firefox 扩展调用 native C 代码?

c# - 指定的 token 太长。最大长度为 128 个字符

c# - "Smart"连接字符串的方法?

c# - 给定类型 ExpressionType.MemberAccess,如何获取字段值?

c# - 如何在 .NET Core 中获取 CPU 名称?