如何从 VC++ 调用托管 DLL(带 GUI)?

Posted

技术标签:

【中文标题】如何从 VC++ 调用托管 DLL(带 GUI)?【英文标题】:How to call managed DLL (with GUI) from VC++? 【发布时间】:2015-01-09 04:01:08 【问题描述】:

我有一个遗留(非 .NET)VC++ 项目,它需要使用一些用 WPF/WCF 编写的新组件。我创建了一个 C# DLL 来包装对 WPF/WCF 的调用。作为测试,我创建了一个 C# 客户端来使用这个 DLL,一切似乎都运行良好。

然后,我按照How to call a managed DLL from native Visual C++ code in Visual Studio.NET or in Visual Studio 2005 的文章创建了用于测试的 VC++ 控制台应用程序。但是,GUI 没有出来。这是我的代码:

#include "stdafx.h"

#import "..\PreDll.tlb" raw_interfaces_only

using namespace PreDll;

int _tmain(int argc, _TCHAR* argv[])

    // Initialize COM.
    HRESULT hr = CoInitialize(NULL);

    // Create the interface pointer.
    ILicPtr pILic(__uuidof(Lic));

    VARIANT_BOOL bResult = FALSE;
    long lResult = 0;

    pILic->Check(&bResult);

    pILic->Add(3, 5, &lResult);

    wprintf(L"The result is %d\n", lResult);

    CoUninitialize();
    return 0;

为了验证,我还包含了 Microsoft 示例中的 Add 方法,该方法运行良好。但是,我对 Check 的函数调用假设会弹出一个对话框,但它永远不会发生。我错过了什么?

【问题讨论】:

“它不出来”不是一个合适的问题描述。 使用 raw_interfaces_only,这只会让您忽略必需的错误检查。这些方法的返回值为 HRESULT,您必须验证它。该值告诉你出了什么问题,IErrorInfo 给你错误信息。 @Hans Passant 如果我删除 raw_interfaces_only,我什至无法编译。错误是“...ILic::Add' : function does not take 3 arguments” 你得到了友好的包装器,long lResult = pILic->Add(3, 5);查看 .tli 文件。 【参考方案1】:

尝试注销并注册

> regsvcs /u myDLL.dll

> regasm myDLL.dll /unregister

> regasm myDll.dll /tlb:myDLL.tlb /codebase


//i hope you have both of them in same interface
public interface ILicPtr

    int Add(int x, int y);
    int Check();
;

【讨论】:

我刚试了一下,还是不行。你能解释一下为什么注销和注册可以解决这个问题吗?对于接口,是的,我所有的方法都在同一个接口中。 正如你所说的 add() 工作正常,我建议你在你的 C# add 函数中调用 check() 以便在你在 c++ 中执行 add() 或可能将日志写入文件时调用它 【参考方案2】:

您能否使用调试器来验证您是否可以从 C++ _tmain 例程进入您的 .net 例程?代码是否干净地返回,或者是否引发了某种异常?如果两个项目在同一个解决方案中,调试应该是无缝的。

你能发布显示弹出窗口的 C# 代码吗?

如果可以从 C++ 进入 C# 没有问题,并且没有发生奇怪的异常,那么我会看看你的 UI 引擎的设置。

【讨论】:

我不能从C++单步到C#,因为我不能直接引用C# dll,我必须先把它转换成TLB,然后在C++项目中导入TLB。

以上是关于如何从 VC++ 调用托管 DLL(带 GUI)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在非托管 c++ dll 中查找调用方程序集名称

非托管C++通过C++/CLI包装调用C# DLL

MFC如何调用DLL(VC++)

从 VB6 调用一个简单的 VC DLL

从 C# 调用非托管 .dll 的性能

从 C# 调用 C++ dll。 “无法封送'返回值':托管/非托管类型组合无效。”