我有一个用C#编写的ActiveX控件,并且在ActiveX兼容程序(CoDeSys)中运行时工作。我遇到的问题是,为了让CoDeSys与ActiveX控件交互,CoDeSys需要dll导出函数原型:
void ExecuteActiveXCall(IUnknown* pUnk, char* pszId, char* pszParam, char* pszReturnBuffer, int nReturnBufferSize, DWORD* pdwReturnFlag);
我看起来没有成功如何在C ++中导出这个,如下例所示:
extern "C" __declspec (dllexport) void ExecuteActiveXCall(IUnknown* pUnk, char* pszId, char* pszParam, char* pszReturnBuffer, int nReturnBufferSize, DWORD* pdwReturnFlag)
{
if (strcmp(pszId, "IWebBrowser|GoBack") == 0)
{
IUnknown* pNewUnk;
IWebBrowser* pwb;
pUnk->QueryInterface(IID_IWebBrowser, (void**) &pNewUnk);
pwb = (IWebBrowser*) pNewUnk;
if (pwb)
{
pwb->GoBack();
pwb->Release();
}
}
else if (strcmp(pszId, "IWebBrowser|GoForward") == 0)
{
IUnknown* pNewUnk;
IWebBrowser* pwb;
pUnk->QueryInterface(IID_IWebBrowser, (void**) &pNewUnk);
pwb = (IWebBrowser*) pNewUnk;
if (pwb)
{
pwb->GoForward();
pwb->Release();
}
}
}
C#确实有一个 extern 关键字,但它不允许你提供函数定义(至少我没找到方法)。尝试之后:
extern unsafe void ExecuteActiveXCall(
[MarshalAs(UnmanagedType.IUnknown)] object pUnk,
char* pszId,
char* pszParam,
char* pszReturnBuffer,
int nReturnBufferSize,
UInt32* pdwReturnFlag)
{
}
发生以下错误:
'AlarmsCSharp.AlarmsControl.ExecuteActiveXCall(object, char*, char*, char*, int, uint*)' cannot be extern and declare a body
是否有人尝试在C#dll中导出函数?
有任何变通方法吗? (我想到了 [DllImport(“AlarmsCSharp.dll”)] 并在C ++ dll中调用了C#,但我想看看之前是否有人有过解决方案。
也许我在想这个并且不需要导出这个函数,因为ActiveX控件已经能够与C#代码进行交互。
编辑:我感觉从C ++函数原型到C#接口声明的翻译。如果对C ++ / C#编程有较多经验的人可以验证我的翻译是否正确或不正确,那么可能会有所帮助。
答案 0 :(得分:0)
你说CoDeSys与ActiveX兼容;你尝试过使用COM互操作吗?
答案 1 :(得分:0)
似乎有3个主要选择;第一种是设置COM互操作,您可以使用COM实例化C#控件/类。我相信如果你做一些搜索,你可以找到更多的信息。
第二个选项是使您的c ++模块混合托管/非托管,如下所述: http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/5345a27a-a614-4a74-9f6d-ea7a999ddf83/
第三个选项是使用“反向PInvoke”,如下所述:http://tigerang.blogspot.com/2008/09/reverse-pinvoke.html
可能还有其他选择;那些是我所知道的。