3

我正在攻读化学博士学位,因此我需要编写一个软件应用程序来帮助我在显微镜下对样品进行成像。该显微镜配有 xyz 纳米定位台。该阶段由硬件供应商使用 VC++ 编写的非托管 DLL 控制。我可以为您提供更多需要的细节,但让我从这个开始;

dll 中的一种方法允许我读取运动轴的设置:

C++ 语法:

BOOL E7XX_qSVO (int ID, const char* szAxes, BOOL* pbValueArray) 

根据惯例,BOOL 是 int 0 或 1。

我的 C# 包装器包含:

[DllImport("E7XX_GCS_DLL.dll", EntryPoint = "E7XX_qSVO")]   
public static extern int qSVO(int iId, string sAxes, int []iValArray);

这对我来说似乎是正确的。但是,当我在我的主应用程序中尝试这样的事情时(查询轴 1,2 和 3):

Int32 [] _iValues = new Int32[3];
E7XXController.qSVO(m_iControllerID, "123", _iValues);

我一直得到这样的数组:

{6, 0, 10} 而根据设备本身的显示我应该得到 {0, 0 , 0} 。互补功能:

BOOL E7XX_SVO (int ID, const char* szAxes, const BOOL* pbValueArray)在舞台上设置相同的状态位也不起作用......

dll 中的其他命令运行良好。我可以毫无问题地传入和传出字符串和双打,但不是 BOOL 类型......

你们知道可能出了什么问题吗?

4

4 回答 4

1

您是否尝试过指定 MarshalAs 属性,例如:-

[DllImport("E7XX_GCS_DLL.dll", EntryPoint = "E7XX_qSVO")]   
public static extern int qSVO(int iId, 
                              [MarshalAs(UnmanagedType.AnsiBStr)]string sAxes, 
                              [MarshalAs(UnmanagedType.LPArray)]int[] iValArray);

另外,您是否尝试过将 sAxes 字符串作为 char 数组直接传递,例如:-

[DllImport("E7XX_GCS_DLL.dll", EntryPoint = "E7XX_qSVO")]   
public static extern int qSVO(int iId, 
                              [MarshalAs(UnmanagedType.LPArray)]char[] sAxes, 
                              [MarshalAs(UnmanagedType.LPArray)]int[] iValArray);

我发现对于互操作,您通常需要进行一些试验才能使其正常工作,因此请尝试不同的组合,检查 UnmanagedType 枚举的不同成员,并考虑其他人的建议。但是,请尝试以上两种技术,让我知道它们是否有助于排序!

于 2009-02-01T03:02:48.637 回答
1

C++ 中的 BOOL 实际上是一个“int”,因此请确保使用 System.Int32 而不是 System.Boolean。或者,它可能使用 COM 数据类型,即 VARIANT_BOOL,在这种情况下,您需要 System.Boolean。您是否尝试过运行依赖查看器来确认函数原型?

于 2009-01-31T22:21:18.063 回答
0

这不会直接回答您的问题,但是使用 Pinvoke.net 轻松获得常见的 Interop Win32 调用的一个很好的工具甚至有一个 Visual Studio 插件。

http://www.pinvoke.net/index.aspx

于 2009-02-01T02:29:19.937 回答
0

您的函数的文档说:

VC++ 编译器需要一个 extern "C" 修饰符。声明还必须指定这些函数将像标准 Win-API 函数一样被调用。这意味着 VC++ 编译器需要在声明中看到 WINAPI 或 __stdcall 修饰符。

的默认调用约定DllImportWinApi。在 Windows 上,这就是 StdCall。但在 CE 上,这是 Cdecl。您要确保使用正确的调用约定。您可能想在托盘中添加:

CallConvention = CallingConvention.StdCall

另外,指定我们的字符串字符集:

CharSet = CharSet.Ansi

但即使没有这些,它也应该工作。这很奇怪,因为您的代码看起来正确。

于 2009-02-01T02:46:54.283 回答