You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用含托管类的C#/CLR .tlb文件对接C++/Qt是否可行?

可行方案指引

方案1:Visual Studio 分文件启用CLR(推荐,最简)

这个方案不需要拆分独立DLL,直接在同一个Qt项目里混合编译,解决你说的全项目开CLR导致Qt代码失效的问题。

  • 前置准备:VS安装Qt VS Tools插件,创建标准Qt Widgets项目,确认原生Qt代码可以正常编译运行。
  • 抽离CLR相关代码:把你调用TLB的逻辑单独拆成两个文件:
    1. 头文件 instrument_adapter.h(纯原生C++语法,无任何CLR相关关键字,可被Qt代码直接引用)
    #ifndef INSTRUMENT_ADAPTER_H
    #define INSTRUMENT_ADAPTER_H
    #include <utility>
    class InstrumentAdapterPrivate;
    class InstrumentAdapter {
    public:
        InstrumentAdapter();
        ~InstrumentAdapter();
        std::pair<int, int> getXY();
    private:
        InstrumentAdapterPrivate* d; // PIMPL不透明指针,隐藏CLR实现细节
    };
    #endif
    
    1. 实现文件 instrument_adapter.cpp(仅这个文件开启CLR支持,包含CLR逻辑)
      把你原来的托管类放在这个cpp里,实现适配器的逻辑:
    #include "pch.h"
    #include "instrument_adapter.h"
    #include <chrono>
    #include <thread>
    using namespace System;
    
    // 托管类和私有实现都放在cpp内部,对外不可见
    public ref class Instrument {
    public:
        TEMEXTLib::TEM3Class ^theScope;
        TEMEXTLib::IDef3^ theDef;
        Instrument() {
            theScope = gcnew TEMEXTLib::TEM3Class();
            theDef = theScope->CreateDef3();
            std::chrono::seconds timespan(2);
            std::this_thread::sleep_for(timespan);
        }
        std::pair<int, int> check() {
            int x;
            int y;
            theDef->GetCLA1(x, y);
            return {x, y};
        }
    };
    
    class InstrumentAdapterPrivate {
    public:
        gcroot<Instrument^> instance; // gcroot用来在原生类里持有托管对象引用
    };
    
    InstrumentAdapter::InstrumentAdapter() : d(new InstrumentAdapterPrivate()) {
        d->instance = gcnew Instrument();
    }
    
    InstrumentAdapter::~InstrumentAdapter() {
        delete d;
    }
    
    std::pair<int, int> InstrumentAdapter::getXY() {
        return d->instance->check();
    }
    
  • 单文件编译配置:右键点击instrument_adapter.cpp -> 属性 -> 【C/C++】-> 【常规】-> 【公共语言运行时支持】选择公共语言运行时支持(/clr),其他所有文件保持默认的无CLR配置即可。
  • 冲突解决:给instrument_adapter.cpp单独关闭【C/C++】-> 【代码生成】-> 【基本运行时检查】设置为默认值,运行库选多线程调试DLL(/MDd)(和Qt项目配置保持一致)。
  • 对接Qt:你直接在Qt的窗口类里引用instrument_adapter.h,创建InstrumentAdapter实例,调用getXY()拿到x、y值后,用QString("X值:%1,Y值:%2").arg(x).arg(y)拼接字符串,调用QLabel::setText()即可展示。

方案2:CLR逻辑编译为独立DLL(兼容性最好)

如果需要用Qt Creator开发,或者后续要做跨平台适配,选这个方案:

  • 单独创建一个VS动态库项目,开启CLR支持,把你调用TLB的逻辑封装成纯C接口导出:
    // dllmain.cpp 或者单独的导出文件
    extern "C" __declspec(dllexport) void* create_instrument() {
        auto ins = gcnew Instrument();
        return GCHandle::ToIntPtr(GCHandle::Alloc(ins)).ToPointer();
    }
    extern "C" __declspec(dllexport) void get_instrument_xy(void* ins, int* x, int* y) {
        GCHandle handle = GCHandle::FromIntPtr(IntPtr(ins));
        Instrument^ instance = safe_cast<Instrument^>(handle.Target);
        auto xy = instance->check();
        *x = xy.first;
        *y = xy.second;
    }
    extern "C" __declspec(dllexport) void destroy_instrument(void* ins) {
        GCHandle handle = GCHandle::FromIntPtr(IntPtr(ins));
        handle.Free();
    }
    
  • 编译得到dll、lib文件后,Qt项目不管是Qt Creator还是VS的都可以直接作为原生C库链接调用,完全不需要开启CLR支持,和调用普通第三方库没有区别。

常见问题说明

  • Qt Creator本身不支持C++/CLI的编译和调试,如果要在Qt Creator里开发,只能用上述方案2,把CLR部分作为独立DLL调用。
  • 不要给Qt相关的代码文件开启CLR支持,只要隔离了CLR代码到单独的文件,Qt的功能完全不会受影响。
  • 跨平台适配的时候,只需要把Windows平台下调用这个CLR DLL的逻辑做个平台判断,非Windows平台用其他对应实现即可,不影响整体代码的移植性。

内容的提问来源于stack exchange,提问作者Bart M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 19:54:04