0

我在调用 C# 中的 C DLL 时遇到问题

C 函数是(我没有 ac 标头或对此的好的规范:()

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 有问题...

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

当我使用 aref时,我总是得到一个AccessViolation error knr12_read()。如果我使用out我得到一个指针,但字符串总是空的,这是不可能的。我什至尝试了asString但我得到了一个on 。refchar*AccessViolation errorknr12_read()

请指导。

4

2 回答 2

3

StringBuilder在对带有字符串返回参数的函数进行 P/Invoking 时,通常是一种很好的类型:

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

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

StringBuilder outString = new StringBuilder(100);

您不应该需要“不安全”,除非“C”代码在指针上的保留时间超过调用持续时间,否则您不必担心固定 - 框架正在为您做这件事。

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

于 2012-10-19T13:41:29.670 回答
0

可能您还没有固定缓冲区。这是如何固定缓冲区数据的示例。

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

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

试试看,如果它对你有帮助,请告诉我。

于 2012-10-19T13:34:46.180 回答