C#AccessViolation /编组中的本机C-DLL

时间:2012-10-19 13:02:58

标签: c# c dll marshalling unmanaged

我在调用C#C#

时遇到问题

C函数是(我没有c头或一个好的规范:()

int knr12_read ( char *kn12, char *ik9, char *wok, char *wlc,
char *plz, char *ort, char *woz ); 

kn12是参数

这是我在C#中尝试过的。

 [return: MarshalAs(UnmanagedType.U4)]
 [DllImport("Knr12.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "knr12_read", CharSet = CharSet.Ansi)] 
unsafe public static extern int knr12_read(out IntPtr buffer, string ik9, string wok, string wlc, string plz, string ort, string woz);

int knr = knr12_read(out pBuffer, knrTemp, "11111", "", "98529", "Suhl", "1");

string data = Marshal.PtrToStringAnsi(pBuffer);

返回的int总是正确的,应该是怎么回事,但是我对ref参数pBuffer有问题......

其他变量的刺痛类型也在起作用......

当我使用ref时,我总是得到AccessViolation error knr12_read()。如果我使用out我会得到一个指针,但字符串总是空的,这可以是的。我甚至试用了String作为ref char* AccessViolation error但我在knr12_read()上获得{{1}}。

请指导。

2 个答案:

答案 0 :(得分:3)

当P /调用带有字符串返回参数的函数时,

StringBuilder通常是一个很好的类型:

static extern int knr12_read(StringBuilder kn12, ...)

在调用函数之前,您需要初始化字符串构建器,如:

StringBuilder outString = new StringBuilder(100);

你不应该需要'unsafe',除非'C'代码保持指针的持续时间超过调用的持续时间,否则你不必担心固定 - 框架正在为你做这个

这是一个应该有用的问题:Marshal "char *" in C#

答案 1 :(得分:0)

可能你没有固定缓冲区。以下是如何固定缓冲区数据的示例。

GCHandle pinnedRawData = GCHandle.Alloc(rawData,
        GCHandleType.Pinned);

固定对象可确保指针有效,因为.Net运行时始终可以在其认为合适时重新分配内存。

尝试一下,让我知道它是否对你有帮助。