【问题标题】:Native C-DLL in C# AccessViolation/MarshallingC# AccessViolation/Marshalling 中的本机 C-DLL
【发布时间】:2012-10-19 13:02:57
【问题描述】:

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

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

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

当我使用ref 时,我总是得到一个AccessViolation error knr12_read()。如果我使用out 我得到一个指针,但字符串总是空的,这不可能。我什至试过Stringref 对应于 char*,但我在 knr12_read() 上得到一个 AccessViolation error

请指导。

【问题讨论】:

    标签: c# c dll marshalling unmanaged


    【解决方案1】:

    StringBuilder 通常是 P/Invoking 带有字符串返回参数的函数时使用的好类型:

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

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

    StringBuilder outString = new StringBuilder(100);
    

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

      • 可能值得补充的是,只有当“C”代码在返回后要保留指针时才需要这样做。
      猜你喜欢
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多