经过一番研究和实验,我仍然不能解决一个问题,即如何从外部库访问非托管函数。
简单的相关背景:我用Visual C++编写了一款应用程序,用于驱动通过USB连接到系统的外部仪表,但它在虚拟串口上运行,并且我注意到输出行为很奇怪。为了证明自己是正确的,制造商要求我使用他们的.dll文件来控制仪表。好吧,但是......
我无法直接包含这个.dll作为引用(已移除名称和路径),因此我可能会使用DllImport来使用它。我决定不直接将代码包含在应用程序中,而是创建我的组件作为驱动程序的包装器,以便可以通过类访问功能。在对.dll执行dumpbin /exports之后,我找到了所有函数的入口点,并创建了一个C#类库,如下所示,只包括相关示例:
功能原型是从他们发给我的描述其库的pdf中提取的:
但在尝试检索序列号后它失败了:
我不太确定哪里出错了。一些函数返回正确的信息,但似乎所有需要传递信息的函数都失败了。我已经尝试了各种字符集和调用约定的组合,将ExactSpelling设置为true等。我是否做错了明显的事情,或者我不能在当前环境中使用这个库?
编辑:我忘记提到,我将'1'传递给函数的原因是,如果系统只连接了一个电表,“Index”将为1。如果有两个电表,我可以通过传入“2”来访问第二个电表。
简单的相关背景:我用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();
};
}
功能原型是从他们发给我的描述其库的pdf中提取的:
SERIALNUMBER (ByVal Index As Byte) As Long
OPENPORT () As Integer
它也被用在他们的VB示例程序中:
Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long
Private Declare Function OpenPort Lib "PortDrv" Alias "OPENPORT" () As Integer
还跟上我吗?好的。编译完我的汇编代码后,我将引用添加到了我的应用程序中,并像这样访问了包装器:
int port_return = PortDrv::OpenPort();
Byte bite = 0x31;
__int64 serial = PortDrv::SerialNumber(bite);
但在尝试检索序列号后它失败了:
![enter image description here](https://istack.dev59.com/MRAQ3.webp)
编辑:我忘记提到,我将'1'传递给函数的原因是,如果系统只连接了一个电表,“Index”将为1。如果有两个电表,我可以通过传入“2”来访问第二个电表。