简体   繁体   English

C#AccessViolation /封送中的本机C-DLL

[英]Native C-DLL in C# AccessViolation/Marshalling

I have a problem with calling a C DLL fom C# 我在调用C DLL fom C#时遇到问题

The C function is (I don't have ac header or a good spec for this :( ) C函数是(我没有ac接针或对此没有好的规格:()

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

kn12 is a ref parameter kn12是参考参数

This is what I've tried in C# 这就是我在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);

The returning int is always right, how it should be, but I have problems with the ref parameter pBuffer... 返回的int总是正确的,应该是正确的,但是ref参数pBuffer存在问题...

Also the sting type for the other variables is working... 其他变量的字符串类型也在起作用...

When I use a ref ,I always get an AccessViolation error knr12_read() .In case I use out I get a pointer,but the String is always empty which can't be.I even tried out String as ref for char* but I get an AccessViolation error on knr12_read() . 当我使用ref ,总是会出现AccessViolation error knr12_read() 。万一我out我会得到一个指针,但是String始终为空,这不可能。我什至尝试将String用作char* ref ,但我在knr12_read()上获得AccessViolation error

Please guide. 请指导。

StringBuilder is often a good type to use when P/Invoking to functions with string returning parameters: P /调用具有字符串返回参数的函数时, StringBuilder通常是一个很好的类型:

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

You'll need to initialise the string builder before you call the function, something like: 在调用函数之前,您需要初始化字符串生成器,例如:

StringBuilder outString = new StringBuilder(100);

You shouldn't need the 'unsafe', and unless the 'C' code holds onto the pointers for longer than the duration of the call, you shouldn't need to worry about pinning - the framework is doing that for you. 您不需要'unsafe',并且除非'C'代码在指针上保留的时间长于调用持续时间,否则您无需担心固定-框架正在为您这样做。

Here's a SO question which should help: Marshal "char *" in C# 这是一个应该有帮助的SO问题: 在C#中封送“ char *”

Probably you have not pinned the buffer. 可能您尚未固定缓冲区。 here is the example of how to pin the buffer data. 这是如何固定缓冲区数据的示例。

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

Pinning the object makes sure that the pointer is valid cause .Net runtime can always reallocate the memory as and when it thinks fit. 固定对象可确保指针有效,因为.Net运行时始终可以在认为合适时重新分配内存。

Try it out and let me know if it helps you. 尝试一下,让我知道它是否对您有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM