我有一个问题,包括我的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配对)
任何人都可以帮助例外吗?我很确定它与方法中的参数类型有关,但我不知道如何正确地声明它们.任何帮助,将不胜感激!
提前致谢
亚历克斯
添加了简短的文档以进行说明
This function takes a string of 16-bit Unicode characters in inbuf and
translates it into a string of 16-bit characters in outbuf.The tableList parameter points to a list of translation tables
separated by commas.Note that both the *inlen and *outlen parameters are pointers to
integers. When the function is called, these integers contain the
maximum input and output lengths, respectively. When it returns, they
are set to the actual lengths used.The typeform parameter is used to indicate italic type, boldface type,
computer braille, etc. It is a string of characters with the same
length as the input buffer pointed to by *inbuf. However, it is used
to pass back character-by-character results, so enough space must be
provided to match the *outlen parameter. Each character indicates the
typeform of the corresponding character in the input buffer. The
values are as follows: 0 plain-text; 1 italic; 2 bold; 4 underline; 8
computer braille. These values can be added for multiple emphasis. If
this parameter is NULL, no checking for type forms is done. In
addition, if this parameter is not NULL, it is set on return to have
an 8 at every position corresponding to a character in outbuf which
was defined to have a dot representation containing dot 7, dot 8 or
both, and to 0 otherwise.The spacing parameter is used to indicate differences in spacing
between the input string and the translated output string. It is also
of the same length as the string pointed to by *inbuf. If this
parameter is NULL, no spacing information is computed.The mode parameter specifies how the translation should be done.
The function returns 1 if no errors were encountered and 0 if a
complete translation could not be done.
这是我在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())?
最佳答案 返回值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参数传递.你必须弄清楚缓冲区需要多大.我假设该函数的文档告诉您如何执行此操作.至少对于初始测试,您可以为typeform和spacing传递null.