c# - 将 C dll 代码编码为 C#

标签 c# c char unmanaged marshalling

我在 dll 中有以下 C 代码签名:

extern __declspec(dllexport) unsigned char *
funct_name (int *w, int *h, char **enc, int len, unsigned char *text, int *lp, int *mp, int *ep)

C 函数可以修改 w、h、enc、lp、mp 和 ep(尽管后三个可以为 null,并且不会执行任何操作。

我在 C# 中使用以下内容

[DllImport("iec16022ecc200.dll", EntryPoint = "iec16022ecc200", ExactSpelling = false, CharSet = CharSet.Ansi, SetLastError = true, CallingConvention=CallingConvention.Cdecl)]
            static extern IntPtr CallEncode(
            [In,Out,MarshalAs(UnmanagedType.LPArray)] Int32[] width,
            [In,Out,MarshalAs(UnmanagedType.LPArray)] Int32[] height,
            [In,Out,MarshalAs(UnmanagedType.LPStr)] ref StringBuilder encoding,
            int barcodeLen,
            [MarshalAs(UnmanagedType.LPStr)] StringBuilder barcode,
            IntPtr lenp,
            IntPtr maxp,
            IntPtr eccp
            );


public void Foo (string textToEncode,out int width, out int height) {
            StringBuilder text = new StringBuilder(textToEncode);
            StringBuilder encoding = new StringBuilder(new string('a', text.Length));

            Int32[] w = new Int32[1];
            Int32[] h = new Int32[1];


            string encodedStr = Marshal.PtrToStringAnsi(CallEncode(w, h, ref encoding, text.Length, text, (IntPtr)0, (IntPtr)0, (IntPtr)0));
            width = w[0];
            height = h[0];
}

我遇到了 SystemAccessViolation,但我不完全确定我的问题是什么时候。

最佳答案

不要将 StringBuilder 引用传递给采用 char* 的非托管方法。 StringBuilder 内容是 unicode (wchar)。

相反,将 StringBuilder 参数替换为 IntPtr 参数,并使用 Marshal.AllocHGlobal 分配适当大小的缓冲区。

此外,我认为 .Net 编码器不支持使用“ref”将 StringBuilder 传递给非托管代码。

关于c# - 将 C dll 代码编码为 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/803488/

相关文章:

c# - 等待任何线程完成,而不是全部

c++ - 如何使用 CreateProcess 将输出重定向到文件?

从 C 中的索引构造字符串

C函数删除字符串

c# - Xml反序列化器不工作

c# - 在文件/目录上设置时间戳非常慢

c - 如何处理动态分配的 struct C 中的段错误

cout<<char(int) 转换上的 C++ EOF

c# - 是否可以使数组大小大小取决于属性值(int)? C#

c - C 中无重复的随机数数组