您的位置:首页 > 其它

.NET CF调用eVC的动态库,Char* 传参问题解决方法。

2008-07-09 00:56 489 查看
做项目时碰到这个问题,在网上搜了半天,资料很少。不过做了多次试验后总算调出来了,放出来供大家参考。eVC函数原型intInit_Port(char*mPort);这个函数需要接收一个Char*参数,指示打开哪个com端口。

privatereadonlyStringComPortName="COM5:";


我需要把ComPortName的值作为参数进行传递。一开始,我定义

[DllImport("ComPort.dll",EntryPoint="Init_Port",CharSet=CharSet.Auto)]
privatestaticexternInt32Init_Port(StringPortName);

调用Init_Port(ComPortName)后没有报异常,但是返回值显示端口打开失败。分析后认为,还是参数传值的时候出了问题。然后先后把PortName声明为StringBuilder---端口打开失败[Marshal.LPArray]String,报Unsupported异常。多次试验后。决定用Byte[]试试看。于是有了以下代码声明部分:[DllImport("ComPort.dll",EntryPoint="Init_Port",CharSet=CharSet.Auto)]

privatestaticexternInt32Init_Port(Byte[]buf);



调用部分:
Byte[]buf=System.Text.Encoding.ASCII.GetBytes(ComPortName);

try

{

Int32iRet=Init_Port(buf);

if(iRet==0)

{

_CurPortState=PortState.Opened;

}

else_CurPortState=PortState.OpenFailed;

}

catch(Exception){_CurPortState=PortState.OpenFailed;}
一次性调试通过。实际上,这个动态库只能接受ASCII编码的参数。但是在Mobile平台,参数的传递是基于Unicode的。有资料说如果eVC将函数声明为WChar_t*,那么直接传递String就可以了。我自己没办法做实验,进做资料的记录。顺便记一下如何从处理IntPtr参数值。
///<summary>

///消息循环,在这里处理消息。

///</summary>

///<paramname="msg"></param>

protectedoverridevoidWndProc(refMessagemsg)

{

switch(msg.Msg)

{

caseWM_SCAN:

try

{

Byte[]Ret=newByte[20];

Marshal.Copy(msg.WParam,Ret,0,20);

TMCode=Encoding.ASCII.GetString(Ret,0,20).Trim(newChar[]{'/0'});

CurScanState=ScanState.Finished;

}

catch(Exception)

{

CurScanState=ScanState.Finished;

}

break;

}

base.WndProc(refmsg);

}
eVC程序利用SendMessage将一个字符串发送到我窗体的handle。因此我首先要处理这个消息循环,相应消息。我需要取得的值被保存在WParam的指针里面。首先声明长度为20的Byte[],之后用Marshal.Copy将Msg.WParam指针指向的内存数据复制到这个数组。然后再利用Encoding.ASCII将Byte[]转换为String。并将结果截断后面的/0。空数据实际上Marshal有一个方法,用于将IntPtr转换为String。名字为Marshal.PtrToStringBSTR(ptr)。然而我的程序里面,调用这个方法会产生内存溢出异常。可能还是源程序写的不够规范吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: