各位达人,小弟最近编程时要用到一用VC6写的DLL,其中有一个接口不知该如何调用,其原型如下:void WordSegment_dll(void* pSegger, char* str, char** pWord, int& wordNum);偶知道C#中可以将void*转化成IntPtr,char*转化成StringBuilder,int&转化成out int。~~但是~~,char**我不会转化。:(
我在C#中这样对上面的char** pWord参数处理:(这里的char** pWord在DLL中是一个N*N的数组。)ArrayList pWord = new ArrayList(N);
for (int i = 0; i < N; i++)
{
pWord.Add(new char[N]);
}然后将C#中的声明写为:[DllImport("IRLAS.dll")]
public static extern void WordSegment_dll(IntPtr pSegger, string line, ArrayList pWord, out int wordNum);编译可以通过,但运行时会抛出AccessViolationException异常:“受保护的内存被破坏”。我觉得这样的类型转换可能有问题,但不知道应该怎么写。请达人们指教!
小弟跪谢!
我在C#中这样对上面的char** pWord参数处理:(这里的char** pWord在DLL中是一个N*N的数组。)ArrayList pWord = new ArrayList(N);
for (int i = 0; i < N; i++)
{
pWord.Add(new char[N]);
}然后将C#中的声明写为:[DllImport("IRLAS.dll")]
public static extern void WordSegment_dll(IntPtr pSegger, string line, ArrayList pWord, out int wordNum);编译可以通过,但运行时会抛出AccessViolationException异常:“受保护的内存被破坏”。我觉得这样的类型转换可能有问题,但不知道应该怎么写。请达人们指教!
小弟跪谢!
char* = string *
呵呵,可以实验一下
char *p 中的p是一个指针 一个4字节的uint 这个地址是一连串Char的开始位置char **p 的p也是一个指针 这个地址是一个N*N的 char的矩阵的开始地址
在内存中的情况 应该是一个N*N个连续的char
也就是说可以 把p看成是一个 有N*N个char 的一维char数组的开始地址
我认为转成IntPtr应该也可以然后用
Marshal.Copy 方法 (IntPtr, Char[], Int32, Int32)
将数据从非托管内存指针复制到托管字符数组。
source
内存指针,从中进行复制。 destination
要复制到的数组。 startIndex
数组中 Copy 开始位置的从零开始的索引。 length
要复制的数组元素的数目。
然后用Marshal.AllocHGlobal (Int32)
使用 GlobalAlloc 从进程的非托管内存中分配内存。
再用
Marshal.Copy (Char[], Int32, IntPtr, Int32)
将数据从一维的托管字符数组复制到非托管内存指针 (把那个N*N看成是一维的)
最后将这个IntPtr传给你的函数以上仅是我的计想 没做过 你试试看 希望对你有帮助
不过问题依然如故~~AccessViolationException
for (int i = 0; i < len; i++)
{
pWord[i] = new char[N];
}这么说来pWord应该是一个字符指针的数组,而不是字符的二维数组。
for (int i = 0; i < len; i++)
{
pWord[i] = Marshal.AllocHGlobal (N);
}
试一试
public static extern void WordSegment_dll(IntPtr pSegger, string line, string[] pWord, out int wordNum);
是不是这样的?
for (int i = 0; i < N; i++)
{
pWord[i] = Marshal.AllocHGlobal (N);
}这个没抛出异常,但……我不知道怎么把它转化回来呢?
我用的方法是
Marshal.Copy(pWord[0], destArray, 0, N); (第0组)
但结果不对。
这里面是不是有编码转化的问题?C#的默认编码是Unicode,而我用的DLL的编码可能是微软的MBCS。
该死……
byte[] destArray = new byte[N];
Marshal.Copy(pWord[0], destArray, 0, N);
string destString = Encoding.GetEncoding("GB2312").GetString(destArray);
destString = destString.Remove(destString.IndexOf('\0'));这就全对了~~
弄了一个月,终于弄出来了~~555~~~谢谢jimgreat大侠!感激之情难以言述~~所以,就用分数表达吧~~