gpt4 book ai didi

C#:Cdecl DllExport,参数中带有指向类实例的指针

转载 作者:太空狗 更新时间:2023-10-29 23:02:21 26 4
gpt4 key购买 nike

我正在考虑为名为 SmartDVB 的软件编写插件。它需要我导出以下函数(这是一个 C++ 示例):

BOOL RegisterAddOn(UINT iAddOnId, IAddOnInterfaces *pInt, AddOnSettings &settings) {
/* ... */
return TRUE;
}

其中IAddonInterfaces是一个抽象类(接口(interface)):

class IAddOnInterfaces {
public:
virtual HRESULT AddSectionFilter(UINT uiAddOnId, UINT pid, BYTE *filter, BYTE *mask, BYTE length, DeviceSettings *pDev) = 0;
virtual HRESULT RemoveSectionFilter(UINT uiAddOnId, UINT pid, DeviceSettings *pDev) = 0;
virtual HRESULT AddFilter(UINT uiAddOnId, UINT pid, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT RemoveFilter(UINT uiAddOnId, UINT pid, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT GetChannel(UINT uiAddOnId, CHANNEL *chn, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT GetTransponder(UINT uiAddOnId, SATELLITE *sat, TRANSPONDER *t, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT SetTransponder(UINT uiAddOnId, SATELLITE sat, TRANSPONDER t, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT CreateOSDElement(UINT uiAddOnId, OSDWindowType type, ULONG &ulId, OSDWindowInfo &info) = 0;
virtual HRESULT ChangeChannel(UINT uiAddOnId, CHANNEL &chn, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT RegisterOSDEvents(UINT iAddOnId, IAddOnOSDEvents *pEvents) = 0;
virtual HRESULT RegisterMenuEvents(UINT iAddOnId, IAddOnMenuEvents *pEvents) = 0;
virtual HRESULT RegisterChnEvents(UINT iAddOnId, IAddOnChnEvents *pEvents) = 0;
virtual HRESULT DoDVBCmd(UINT iAddOnId, BYTE pCmd, UINT uiLen, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT DoDiseqc(UINT iAddOnId, CHANNEL &chn, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT RecordBusy(UINT iAddOnId, BOOL *bBusy, DeviceSettings *pDev=NULL) = 0;
virtual HRESULT GetDeviceSettings(UINT iAddOnId, DeviceSettings &Dev) = 0;
virtual HRESULT GetSignalStrength(UINT iAddOnId, LONG *lStrength, DeviceSettings *Dev) = 0;
virtual HRESULT GetSignalQuality(UINT iAddOnId, LONG *lQuality, DeviceSettings *Dev) = 0;
};

AddOnSettings 是一个结构体:

typedef struct _AddOnSettings{
HINSTANCE hInst; // SmartDVB application instance
HWND hwnd;
TCHAR name[256]; // addon name
HMENU menu; // addon popup menu
WORD idmenustart;
} AddOnSettings;

在c#中,我将结构定义为

using HINSTANCE = System.IntPtr;
using HWND = System.IntPtr;
using HMENU = System.IntPtr;

/* ... */

public unsafe struct AddOnSettings{
HINSTANCE hInst; // SmartDVB application instance
HWND hwnd;
[MarshalAs(UnmanagedType.LPArray, SizeConst = 256)]
char[] name; // addon name
HMENU menu; // addon popup menu
ushort idmenustart;
};

/* ... */

但是,我仍然需要以某种方式定义类,以便可以将其导出。

最后,我想要这样的东西:

    [DllExport("RegisterAddOn", CallingConvention = CallingConvention.Cdecl)]
public static bool RegisterAddOn(uint iAddOnId, IAddOnInterfaces* pInt, ref AddOnSettings settings)
{
/* ... */
return true;
}

问题是,当我这样做时,出现以下错误:

Error   1   Cannot take the address of, get the size of, or declare a pointer to a managed type ('ChannelSwitchCS.IAddOnInterfaces')    D:\Work\coding\projects\buster\smartdvb\ChannelSwitchCS\ChannelSwitchCS\Class1.cs   102 28  ChannelSwitchCS

附言我不要求完整的解决方案,我只需要了解这种特殊情况,即如何(以及是否可能)在导出函数中拥有指向类实例的指针。因此,我确实意识到我将不得不转换在 IAddOnInterfaces 的方法中使用的所有其他结构和类。

最佳答案

当我不得不使用 PInvoke 并且需要将类的实例作为指针传递时,我为我将在 C++ 中使用的非托管代码编写了一个简单的包装器,它只接受原始类型并将它们排列成任何类型需要。

在将指针传递给类的实例时,我使用了 IntPtr,一切都按照我的预期进行。

关于C#:Cdecl DllExport,参数中带有指向类实例的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28805100/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com