我在Unity C#中工作,试图与用ada编写的dll集成。我需要将包含字符串和双精度的类传递给dll以便修改并返回,但是我收到以下错误: "传递给非托管代码的类型System.Text.StringBuilder必须具有StructLayout属性。"
现在,这些类已经有了一个StructLayoutAttribute。而且我不能在Stringbuilder上放置StructLayout属性,Unity告诉我它只适用于类和结构。这让我对错误信息感到困惑,因为它似乎在问我一些不可能的事情?
public class controller : MonoBehavior{
myClass student = new myClass();
[DllImport ("my_dll", EntryPoint="myFunction@12")]
public static extern void myFunction(myClass c);
void Start(){
myFunction (student);
}
}
[StructLayoutAttribute(LayoutKind.Sequential, size=2)]
public class myClass {
public double height = 0.0;
public System.Text.StringBuilder name = new System.Text.StringBuilder(16);
}
答案 0 :(得分:0)
关于这一点肯定感觉不到。如果您的Ada DLL知道如何处理System.Text.StringBuilder那么这看起来几乎是神奇的。在处理本机库时,通常需要传递原始类型。此外,这个Ada DLL可能不是本机dll,这是Mono期望使用的。有关封送数据的详细信息,请参阅Interop With Native Libraries。
现在假设您的Ada DLL实际上是本机DLL。它以某种方式知道如何处理StringBuilder。您可以通过IntPtr将void指针传递给内存地址。但我非常怀疑这会奏效。你很可能想要做的是传递实际的字符串:
public class controller : MonoBehavior{
myClass student = new myClass();
[DllImport ("my_dll", EntryPoint="myFunction@12")]
public static extern void myFunction(myClass c);
void Start(){
student.name = "John Doe";
myFunction (student);
}
}
[StructLayoutAttribute(LayoutKind.Sequential, size=2)]
public class myClass {
//The following MarshalAs may be unnecessary.
[MarshalAs (UnmanagedType.LPStr)]
public string name;
public double height = 0.0;
}
LPStr是'指向字符串的长指针'。假设您的Ada DLL将知道如何处理它。如果这不起作用,那么你可以删除MarshalAs,看看它是否更喜欢它。
此C函数将采用必须小于~250个字符的输入str并返回修改后的字符串。你会看到它mallocs一个字符串大小为sprintf的修改后的字符串,然后strcopy就是它。没有相应的free()因为它将被mono as mentioned here.
释放 char* myFunction(char* input, double height)
{
char buffer[256];
int n = sprintf(buffer, "%s -- %f", input, height);
char* ret = (char*)malloc(n+1); // +1 for the newline
strcopy(ret, buffer);
return ret;
}
答案 1 :(得分:0)
IIRC C#默认使用PlatformInvoke功能时将StringBuilder编组为char *。这对于与C调用约定DLL的接口很方便。一些Ada编译器(尤其是GCC编译器)可能允许Ada库针对C调用约定进行优化。事实上,“几乎神奇”的本质可能是真实的。 :)
我的建议:用一个不安全的{}块围绕你的C#调用Ada函数并修复你的char数组,然后将它传递给你的Ada函数,然后在它返回后再次退出固定块。
我没有Visual Studio的工作副本,所以我无法验证这一点。
(编辑用于修正错误的术语)