B L*_*B L 4 .net c# vb6 dll pinvoke
经过大量的研究和实验,我仍然无法弄清楚我从外部库中访问未管理的函数时遇到的问题.
快速相关的背景故事:我在Visual C++中编写了一个应用程序,用于驱动通过USB连接到系统的外部仪表,但正在虚拟化串口,我注意到了奇怪的输出行为.为了维护自己,制造商希望我使用他们的.dll来控制我的应用程序中的仪表.很好,但....
我无法直接将此.dll作为参考包含(名称和路径已删除):
所以为了使用它,我想起了DllImport.我决定将自己的程序集作为驱动程序的包装器,而不是将代码直接包含在我的应用程序中,因此我可以通过类访问该功能.在.dll上执行dumpbin/exports之后,我找到了所有函数的入口点,并创建了一个C#类库,只包括相关的示例:
namespace Meter
{
public class PortDrv
{
[DllImport("PortDrv.dll", EntryPoint = "SERIALNUMBER",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Auto)]
public static extern long SerialNumber(Byte Index);
[DllImport("PortDrv.dll", EntryPoint = "OPENPORT",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Auto)]
public static extern int OpenPort();
};
}
Run Code Online (Sandbox Code Playgroud)
函数原型是从他们发给我描述他们库的.pdf中提取的:
SERIALNUMBER (ByVal Index As Byte) As Long
OPENPORT () As Integer
Run Code Online (Sandbox Code Playgroud)
并且还用于他们的示例VB程序:
Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long
Private Declare Function OpenPort Lib "PortDrv" Alias "OPENPORT" () As Integer
Run Code Online (Sandbox Code Playgroud)
还在我这儿?好.因此,在编译我自己的程序集之后,我添加了对我的应用程序的引用并访问了包装器:
int port_return = PortDrv::OpenPort();
Byte bite = 0x31;
__int64 serial = PortDrv::SerialNumber(bite);
Run Code Online (Sandbox Code Playgroud)
但是在尝试检索序列号后它会爆炸:
而且我不太确定我哪里出错了.某些函数会返回正确的信息,但看起来我必须将信息传递给失败.我已经尝试了CharSets和CallingConventions的所有不同组合,我将ExactSpelling设置为true,等等.有什么明显我做错了,或者我可以在当前环境中不使用这个库吗?
编辑:我忘了提到,我将'1'传递给函数的原因是,如果只有一个仪表连接到系统,"索引"将是1.如果有2米,我可以访问第二个传球'2'.
您提供的示例VB程序:
Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long
Run Code Online (Sandbox Code Playgroud)
不说ByVal.VB中的默认值是ByRef.这是你的错字还是问题?如果是这样,你需要ref Byte在签名中说出SerialNumber.
道德:总是说ByRef或ByVal.
| 归档时间: |
|
| 查看次数: |
1240 次 |
| 最近记录: |