c++ - 在调用中使用结构从 vb.net 调用

标签 c++ vb.net pinvoke struct

我真的很难处理以下 pinvoke 调用。我尝试了很多不同的方法来做到这一点,但仍然没有快乐。

调用通过,但我收到一条“错误参数”消息,提示结构有问题,因为我已经运行了这段代码的 C++ 示例并且参数都是正确的。

如果有任何帮助,我将不胜感激,我已经疯狂地用谷歌搜索了自己!

在c++头文件中:

int __stdcall DVSNET_OpenChannel(HANDLE hServer,unsigned long nChannel,DVSNET_CHANNEL_INFO *pChannelInfo,HANDLE *phChannel);

typedef struct tagDVSNET_CHANNEL_INFO
{
    unsigned long lStructSize;
    unsigned long dwStreamNo;
    unsigned long nProtocol;
    HWND          hWndDisplay;
    unsigned long bPlayStart;
    unsigned long dwBackFrameCount;
    unsigned long dwFlag;
} DVSNET_CHANNEL_INFO;

我对导入的定义:

<DllImport("DVSNETClient.dll")> _
Public Shared Function DVSNET_OpenChannel(ByVal hServer As System.IntPtr, ByVal nChannel As UInteger, ByRef pChannelInfo As IntPtr, ByRef phChannel As IntPtr) As Integer
End Function

<StructLayout(LayoutKind.Sequential)> _
Public Structure tagDVSNET_CHANNEL_INFO
    Public lStructSize As UInteger
    Public dwStreamNo As UInteger
    Public nProtocol As UInteger
    Public hWndDisplay As IntPtr
    Public bPlayStart As UInteger
    Public dwBackFrameCount As UInteger
    Public dwFlag As UInteger
End Structure

我的调用代码:

Private Sub OpenChannel()
    Dim intRet As Integer
    Dim ChannelInfo As New tagDVSNET_CHANNEL_INFO

    Dim HWD As New System.IntPtr

    ChannelInfo.lStructSize = System.Runtime.InteropServices.Marshal.SizeOf(ChannelInfo)
    ChannelInfo.nProtocol = 0
    ChannelInfo.dwStreamNo = 0
    ChannelInfo.dwBackFrameCount = 10
    ChannelInfo.hWndDisplay = HWD
    ChannelInfo.bPlayStart = 0 ' dont display
    'Channelinfo.dwFlag = 

    ' Initialize unmanged memory to hold the struct.
    Dim ptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ChannelInfo))
    System.Runtime.InteropServices.Marshal.StructureToPtr(ChannelInfo, ptr, True)

    Dim nChannel As UInteger = 1
    intRet = TotemPoleLib.DVSNET_OpenChannel(hServer, nChannel, ptr, hChannel)

    '... snip ...
End Sub

非常感谢!

最佳答案

我不知道 VB.Net 语法,但如果您了解 C#,那么这里是 DVSNET_CHANNEL_INFODVSNET_OpenChannel 的正确 P/Invoke 声明:

[StructLayout(LayoutKind.Sequential)]
struct DVSNET_CHANNEL_INFO
{
    uint   lStructSize;
    uint   dwStreamNo;
    uint   nProtocol;
    IntPtr hWndDisplay;
    uint   bPlayStart;
    uint   dwBackFrameCount;
    uint   dwFlag;
}

static class DVSNETClient
{
    [DllImport("DVSNETClient.dll")]
    public static extern int DVSNET_OpenChannel(
        IntPtr hServer,
        uint nChannel,
        ref DVSNET_CHANNEL_INFO pChannelInfo,
        ref IntPtr phChannel
    );
}

您的 DVSNET_CHANNEL_INFO 看起来不错,但是 DVSNET_OpenChannel 的第三个参数应该只是一个 ref DVSNET_CHANNEL_INFO;所有的编码(marshal)处理都是自动为你完成的,这里不需要 Marshal 类。您需要做的唯一是在调用之前将ChannelInfo.lStructSize初始化为Marshal.SizeOf(typeof(DVSNET_CHANNEL_INFO))的值>DVSNET_OpenChannel。在 DVSNET_CHANNEL_INFO 的非默认构造函数中执行此操作可能是明智的,但鉴于它是一个结构,当然没有办法在隐式默认构造函数上强制使用该构造函数。

请注意,从语义上讲,pChannelInfo 和/或 phChannel 可能应该是 out 而不是 ref,但是无法通过 DVSNET_OpenChannel 的签名来判断。在任何情况下,使用 ref 都可以正常工作,尽管如果确实需要 out,它的效率将低于使用 out

关于c++ - 在调用中使用结构从 vb.net 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5867864/

相关文章:

mysql - 删除VB.NET中的SQL语句

c# - WCF 错误架构

c# - 从另一个进程获取win32线程的StartAddress

c++ - 如何将输入限制为仅数字

c++ - 如何使用 const_cast?

c++ - 字符串类型是标量吗?如果是,为什么?

c++ - C 传递字符作为引用

c# - 使用 AccountManagement *快速*将多个用户添加到 AD 组

c# - 灯光 USB OpenDMX FTD2XX DMXking

c# - 将 C 结构移植到 C#