开发一个控制LED显示屏的程序。其中需要调用厂家给的DLL中的函数。由于厂家给的开发手册很混乱,里面的内容的可信度不高(有的函数和用工具查看出来的函数名都不一致,有的函数本来没用,手册上却写着有用),只能参考他们给的例子。由于例子中只有VB和c版本的,函数的声明只好自己来。在调用一个函数的时候,总是报“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”异常。这个函数中在他们的例子中是这样声明的:[VB]
Declare Sub LED_SendToScreen Lib "LEDSender.dll" (ByVal dev As Long, ByVal Address As Byte, ByVal Host As String, ByVal Port As Long)[C]
void (_stdcall *LED_SendToScreen)(long dev, BYTE Address, char *Host, WORD port);我在C#中使用了如下的一些声明,都没有成功
public static extern void LED_SendToScreen(int DEV, byte Address, string Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, StringBuilder Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, ref string Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, out string Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, ref StringBuilder Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, out StringBuilder Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, char[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, byte[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, ref char[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, ref byte[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, out char[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, out byte[] Host, UInt16 Port);以上的这些方式我都已经试过了,不知道错误到底在哪。问厂家,厂家的答复是他们的产品没有问题。郁闷中,望高人指点。
Declare Sub LED_SendToScreen Lib "LEDSender.dll" (ByVal dev As Long, ByVal Address As Byte, ByVal Host As String, ByVal Port As Long)[C]
void (_stdcall *LED_SendToScreen)(long dev, BYTE Address, char *Host, WORD port);我在C#中使用了如下的一些声明,都没有成功
public static extern void LED_SendToScreen(int DEV, byte Address, string Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, StringBuilder Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, ref string Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, out string Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, ref StringBuilder Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, out StringBuilder Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, char[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, byte[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, ref char[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, ref byte[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, out char[] Host, UInt16 Port);
public static extern void LED_SendToScreen(int DEV, byte Address, out byte[] Host, UInt16 Port);以上的这些方式我都已经试过了,不知道错误到底在哪。问厂家,厂家的答复是他们的产品没有问题。郁闷中,望高人指点。
[C]
void (_stdcall *LED_SendToScreen)(long dev, BYTE Address, char *Host, WORD port);
public static extern void LED_SendToScreen(long DEV, byte Address, StringBuilder Host, UInt16 Port);
这个试验下
http://topic.csdn.net/u/20070727/15/af8a6093-c0a0-4a31-bba9-f57d8a984223.html
string str = Marshal.PtrToStringAnsi(ptr);
能够写的再详细点吗?你的意思是先将string转成IntPtr,调用的时候用IntPtr?
Declare Sub LED_SendToScreen Lib "LEDSender.dll" (ByVal dev As Long, ByVal Address As Byte, ByVal Host As String, ByVal Port As Long) [C]
void (_stdcall *LED_SendToScreen)(long dev, BYTE Address, char *Host, WORD port);
根据2个比较,可以看出vb中第一参数和第4参数都是long,vb中long应该是32位的,那么c中,1、4参数就不合理了,第一个参数32位,第4个是16位,所以vb版本和c版本不同的声明。
这样看来第2参数基本没有异议,第3参数vb中看应该是知识传入的字符串不传出的,所以应该是string,不过也可以尝试下 Stringbuilder。
第一参数看起来就应该是C#中的int
第4参数我认为可以试验下System.UInt16 和System.UInt32
另外看C版本,感觉如果那个函数指针有可能是定义在返回值中的,如果是可以尝试如下
public static extern IntPtr LED_SendToScreen(int DEV, byte Address, string Host, UInt32 Port);
不是就尝试下
public static extern void LED_SendToScreen(int DEV, byte Address, string Host, UInt32 Port);
我琢磨调用dll最重要是注意参数的类型