我的C#项目中有一个包含DLL(用C语言编写)的问题,希望你能帮到我。在我的研究中,我发现了DLLImport,但我不确定C变量转换为哪种类型......
我要导入的DLL中的C方法如下:
int lou_translateString (
const char * tableList,
const widechar * inbuf,
int *inlen,
widechar *outbuf,
int *outlen,
char *typeform,
char *spacing,
int mode);
这是我试过的DLLImport:
[DllImport("liblouis-2.dll", EntryPoint = "lou_translateString", CharSet = CharSet.Ansi, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern int translate([MarshalAs(UnmanagedType.LPStr)]
String tableList,
String inbuf,
int inlen,
String outbuf,
int outlen,
String typeform,
String spacing,
int mode);
但是当我尝试调用我得到的方法时:
MarshallDirectiveException 无法封送“返回值”:无效的托管/非托管类型组合 (Int32 / UInt32必须与I4或U4配对)
任何人都可以帮忙解决这个问题吗?我很确定它与方法中的参数类型有关,但我不知道如何正确地声明它们。任何帮助将不胜感激!
提前致谢 亚历
添加了简短的文档以进行说明
此函数在inbuf和中使用一串16位Unicode字符 在outbuf中将其转换为一个16位字符串。
tableList参数指向转换表列表 以逗号分隔。
请注意,* inlen和* outlen参数都是指针 整数。调用该函数时,这些整数包含 最大输入和输出长度。当它返回时,它们 设置为实际使用的长度。
typeform参数用于表示斜体类型,粗体字型, 电脑盲文等。它是一串相同的字符 length作为* inbuf指向的输入缓冲区。但是,它被使用 传回逐个字符的结果,所以必须有足够的空间 提供匹配* outlen参数。每个字符表示 输入缓冲区中相应字符的typeform。该 值如下:0纯文本; 1斜体; 2大胆; 4下划线; 8 电脑盲文。可以添加这些值以进行多次强调。如果 此参数为NULL,不检查类型表单。在 另外,如果此参数不为NULL,则返回时设置为 每个位置的8对应于outbuf中的一个字符 定义为包含点7,点8或点的点表示 两者,否则为0。
间距参数用于指示间距的差异 输入字符串和已翻译的输出字符串之间。也是 与* inbuf指向的字符串长度相同。如果这 参数为NULL,不计算间距信息。
mode参数指定应如何进行翻译。
如果没有遇到错误,则函数返回1,如果是,则返回0 无法完成翻译。
这是我在Main中测试函数所写的内容:
StringBuilder outbuf = new StringBuilder("Test", 30);
int inlength = 100;
int louint = 0;
int outlength = 100;
String inbuf = "test";
louint = lou_translateString("de-de-g1.ctb", inbuf, inlen: ref inlength, outbuf: outbuf, outlen: ref outlength, typeform: null, spacing: null, mode: 8);
但最后原来的outbuf根本没有改变。你会说参数是对的吗?我是否必须以某种方式修改outbuf参数,因为它是一个StringBuilder而不仅仅是一个String(outbuf.Replace())?
答案 0 :(得分:2)
返回值MarshalAs
错误。返回值为int
而不是字符串。这解释了错误,但还有更多。你的pinvoke声明的其余部分有错误。我会这样做:
[DllImport("liblouis-2.dll", CharSet = CharSet.Unicode)]
public static extern int lou_translateString(
[MarshalAs(UnmanagedType.LPStr)]
string tableList,
string inbuf,
ref int inlen,
StringBuilder outbuf,
ref int outlen,
[MarshalAs(UnmanagedType.LPStr)]
StringBuilder typeform,
[MarshalAs(UnmanagedType.LPStr)]
StringBuilder spacing,
int mode
);
必须将从函数编组的文本缓冲区声明为StringBuilder
。你还有其他一些错误。将int*
翻译为ref int
。
为了调用该函数,您需要创建一个StringBuilder
的新实例作为outbuf
参数传递。你必须弄清楚缓冲区需要多大。我假设该函数的文档告诉您如何执行此操作。至少在初始测试中,您可以null
传递typeform
和spacing
。