为了账号安全,请及时绑定邮箱和手机立即绑定

如何从C#使用结构指针参数调用C ++函数?

如何从C#使用结构指针参数调用C ++函数?

C#
GCT1015 2021-05-18 17:03:16
好的,还有一个功能,它还没有工作。我基本上是通过使用P / Invoke从C#调用一些C ++函数的。有问题的功能确实会向演出激光设备查询一些与设备有关的信息,例如最小和最大扫描速率以及每秒最大点数。有问题的功能是:int GetDeviceInfo(DWORD deviceIndex, DeviceInfo* pDeviceInfo);这是我得到的C ++头文件。这是非常简短的C ++ SDK描述的链接。我没有重建DLL文件的源,也没有* .pdb文件(制造商无法提供):#pragma once#ifdef STCL_DEVICES_DLL#define STCL_DEVICES_EXPORT extern "C" _declspec(dllexport) #else#define STCL_DEVICES_EXPORT extern "C" _declspec(dllimport)#endifenum SD_ERR{    SD_ERR_OK = 0,    SD_ERR_FAIL,    SD_ERR_DLL_NOT_OPEN,    SD_ERR_INVALID_DEVICE,  //device with such index doesn't exist    SD_ERR_FRAME_NOT_SENT,};#pragma pack (1)struct LaserPoint{    WORD x;    WORD y;    byte colors[6];};struct DeviceInfo{    DWORD maxScanrate;    DWORD minScanrate;    DWORD maxNumOfPoints;    char type[32];};这是我当前正在使用的完整C#测试代码。除以下功能外,所有功能均正常运行第64行(cp屏幕截图):int r4 = GetDeviceInfo(0, ref pDevInfo); 我收到以下错误:An unhandled exception of type 'System.NullReferenceException' occured in MonchaTestSDK.exeAdditional information: Object reference not set to an instance of an object这是堆栈跟踪(如果没有DLL的* .pdb文件,就无法提供更好的堆栈跟踪):MonchaTestSDK.exe!MonchaTestSDK.Program.Main(string [] args)第73行+ 0xa字节C#mscoreei.dll!73a8d91b()[下面的帧可能不正确和/或丢失,没有为mscoreei.dll加载任何符号]mscoree.dll !73cae879()mscoree.dll!73cb4df8()kernel32.dll!74a08654()ntdll.dll!77354b17()ntdll.dll!77354ae7()一些拆卸:            int r4 = GetDeviceInfo(0, ref pDevInfo);05210749  int         3  0521074A  push        ebp  0521074B  cwde  0521074C  xor         ecx,ecx  0521074E  call        0521011C  05210753  int         3  05210754  test        dword ptr [eax-1],edx  05210757  ?? ?? 05210758  dec         dword ptr [ebx-0AF7Bh]  0521075E  dec         dword ptr [ecx-6F466BBBh]知道我在这里做错了吗?
查看完整描述

3 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

正确的应该是


string UnpackFixed(byte[] data, System.Text.Encoding encoding)

{

    int i;

    for (i = 0; i < data.Length; ++i)

        if(data[i] == (byte)0)

            break;

    return encoding.GetString(data, i);

}


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

struct DeviceInfo

{

    uint32 maxScanrate;

    uint32 minScanrate;

    uint32 maxNumOfPoints;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]

    byte type[];

};


DeviceInfo pDevInfo = new DeviceInfo();

pDevInfo.type = new byte[32];

int r4 = GetDeviceInfo(0, ref pDevInfo);

Console.WriteLine("  - type: " + UnpackFixed(pDevInfo.type));

我敢肯定有一种方法可以做到这一点,string但是所有古老的显而易见的方法都倾向于将字符串传递给本机代码,并且什么也得不到。在这里,练习是找回固定长度的字节字符串。如果确实为字符串解决了问题,那么最终将使用System.Text.Encoding.Default正确或不正确的字符串,并且没有任何方法可以覆盖它。


System.Text.Encoding.ASCII可能是错误的,在这种情况下,您需要处理编码。System.Text.Encoding.Default也许可以在ASCII不工作的地方工作,在这种情况下,您应该考虑在多字节字符编码上是否有奇怪的失败模式。目前尚不清楚设备是始终使用与操作系统相同的编码,还是采用固定编码(在这种情况下,您应指定编码)。


查看完整回答
反对 回复 2021-05-23
  • 3 回答
  • 0 关注
  • 228 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信