【问题标题】:How to define dllimport of c++ function with void *buffer in C#如何在 C# 中使用 void *buffer 定义 c++ 函数的 dllimport
【发布时间】:2021-06-06 00:13:29
【问题描述】:

我正在尝试使用 C++ DLL S6145usb.dll 与照片打印机 CHC-S6145 集成。那里定义了一个函数,如下所示。我想知道它的映射 c# DLL 导入是什么。

函数名称 - chcusb_getPrinterInfo

格式

BOOL APIENTRY chcusb_getPrinterInfo (WORD tagNumber, void *rBuffer, DWORD *rLen); 

功能详情 根据标签标识获取指定打印机的信息。

【问题讨论】:

    标签: c# c winapi syntax dllimport


    【解决方案1】:

    BOOL 是 Win32 中的 32 位整数。 PInvoke 有一个Boolean 类型,可以通过MarshalAs 将其封送为32 位整数。

    WORD 是一个 16 位无符号整数。 C# 有一个 Uint16 类型。

    void* 是一个原始指针。 C# 使用 (U)IntPtr 类型。

    DWORD 是一个 32 位无符号整数。 C# 有一个 UInt32 类型。

    另一方面,DWORD* 是指向DWORD 的指针。 C# 具有 refout 说明符,用于通过引用传递参数变量。您需要使用哪一个取决于参数是输入/输出 (ref) 还是仅输出 (out)。

    试试这样的:

    [DLLImport("S6145usb.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern Boolean chcusb_getPrinterInfo(UInt16 tagNumber, IntPtr rBuffer, ref UInt32 rLen);
    
    ...
    
    UInt32 bufLen = ...;
    IntPtr buffer = Marshal.AllocHGlobal((int)bufLen);
    chcusb_getPrinterInfo(..., buffer, ref bufLen);
    // use buffer as needed...
    Marshal.FreeHGlobal(buffer);
    

    【讨论】:

    • 最后的参数可能是refout。它是哪一个没有反映在签名中。该信息需要在随附文档中详细说明。
    • 感谢您的回复,当我调用这个时,我应该如何传递 IntPtr rBuffer 参数?我的意思是我应该创建 IntPtr 的对象并发送吗?
    • 函数调用正在工作,它也返回真(无错误)。但是 IntPtr 不会得到任何分配。当我使用下面的代码时,它会返回错误说源不能为空。字节[] managedArray = 新字节[28]; Marshal.Copy(intPtr, managedArray, 0, 28);
    • @AsankaDilruk 该函数可能希望您分配一个足够大的缓冲区,然后传入指向该缓冲区的指针。您可以使用Marshal.AllocHGlobal() 进行该分配。 rLen 参数可能是输入/输出,因此您可以指定输入时缓冲区的大小,该函数可以返回输出时实际使用的大小。但是您必须检查函数的文档以验证这一点。
    • @RemyLebeau,感谢您在这里提供的所有支持。是的,你是正确的 rLen 是输出大小。对于这个特定的标签 (4),它将根据规范返回 28 个字节。如果你能给我一个小代码示例来定义 IntPtr 并分配 28 个字节并传递给上述方法,那将很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多