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

如何在32位C项目中调用64位C#项目的方法?

可行的实现方案

方案一:COM互操作(推荐跨位数场景)

32位和64位进程无法直接加载对方的DLL,COM通过跨进程调用机制可以解决这个位数不匹配问题。

  • 配置C#项目
    1. 将C#项目设为类库,在项目属性的“生成”标签页勾选“使程序集COM可见”
    2. 给需要暴露给C的类和方法加上[ComVisible(true)]属性:
      [ComVisible(true)]
      public class CsMethods
      {
          public string GetCSharpMessage()
          {
              return "这是来自C#方法的返回值";
          }
      }
      
    3. 生成项目后,用64位版本的regasm.exe注册COM组件(路径通常是C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe):
      regasm.exe YourCSharpLibrary.dll /codebase
      
  • 在32位C项目中调用
    1. 通过CoCreateInstance创建C# COM对象,调用对应方法。示例代码:
      #include <windows.h>
      #include <stdio.h>
      
      int main()
      {
          HRESULT hr = CoInitialize(NULL);
          if (SUCCEEDED(hr))
          {
              CLSID clsid;
              // 替换成你的C#类的ProgID,格式是「命名空间.类名」
              hr = CLSIDFromProgID(L"YourNamespace.CsMethods", &clsid);
              if (SUCCEEDED(hr))
              {
                  IDispatch* pDispatch = NULL;
                  // 用CLSCTX_LOCAL_SERVER指定跨进程调用
                  hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pDispatch);
                  if (SUCCEEDED(hr))
                  {
                      // 这里省略了DISPID查找和方法调用的细节,实际需要按照COM调用规范处理参数与返回值
                      printf("成功调用C# COM组件\n");
                      pDispatch->Release();
                  }
              }
              CoUninitialize();
          }
          return 0;
      }
      
    2. 编译32位C项目,直接运行即可跨进程调用64位C#组件。

方案二:中间代理进程

自己实现一个64位的代理程序,让32位C项目和代理进程通信,代理进程再调用64位C#类库。通信方式可选命名管道、TCP套接字或共享内存,这里以命名管道为例:

  • 编写64位代理程序(C#控制台程序)
    using System.IO.Pipes;
    using System.Text;
    
    class CSharpProxy
    {
        static void Main()
        {
            using (var pipeServer = new NamedPipeServerStream("CSharpCallProxy", PipeDirection.InOut))
            {
                pipeServer.WaitForConnection();
                byte[] buffer = new byte[256];
                int readLen = pipeServer.Read(buffer, 0, buffer.Length);
                string request = Encoding.ASCII.GetString(buffer, 0, readLen);
    
                // 调用目标C#项目的方法
                var result = new YourNamespace.CsMethods().GetCSharpMessage();
                
                byte[] response = Encoding.ASCII.GetBytes(result);
                pipeServer.Write(response, 0, response.Length);
            }
        }
    }
    
  • 32位C项目中与代理进程通信
    #include <windows.h>
    #include <stdio.h>
    
    int main()
    {
        HANDLE pipeHandle = CreateFile(
            L"\\\\.\\pipe\\CSharpCallProxy",
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            0,
            NULL);
    
        if (pipeHandle != INVALID_HANDLE_VALUE)
        {
            char callCmd[] = "InvokeCSharpMethod";
            DWORD bytesWritten;
            WriteFile(pipeHandle, callCmd, sizeof(callCmd), &bytesWritten, NULL);
    
            char response[256];
            DWORD bytesRead;
            ReadFile(pipeHandle, response, sizeof(response), &bytesRead, NULL);
            printf("C#方法返回:%s\n", response);
    
            CloseHandle(pipeHandle);
        }
        return 0;
    }
    
  • 运行流程:先启动64位代理程序,再启动32位C程序,即可完成跨位数调用。

方案三:统一进程位数(如果业务允许)

如果可以把C项目改为64位编译,那么可以直接用UnmanagedExports NuGet包替代你之前尝试的dllExport,步骤如下:

  • 给C#类库安装UnmanagedExports NuGet包
  • 给要暴露的方法添加[DllExport]属性:
    public class CsMethods
    {
        [DllExport]
        public static string GetCSharpMessage()
        {
            return "来自C#的直接调用结果";
        }
    }
    
  • 编译64位C#类库,在64位C项目中导入调用:
    #include <windows.h>
    #include <stdio.h>
    
    typedef const char* (*GetMessageFunc)();
    
    int main()
    {
        HMODULE csDll = LoadLibraryA("YourCSharpLibrary.dll");
        if (csDll != NULL)
        {
            GetMessageFunc getMsg = (GetMessageFunc)GetProcAddress(csDll, "GetCSharpMessage");
            if (getMsg != NULL)
            {
                const char* result = getMsg();
                printf("C#返回:%s\n", result);
                // 注意:如果返回的字符串是C#分配的,需要额外实现释放方法避免内存泄漏
            }
            FreeLibrary(csDll);
        }
        return 0;
    }
    
  • 你之前用dllExport无效很大概率是因为32位C尝试加载64位DLL,位数不匹配导致加载失败,统一为64位后就能正常工作。

内容的提问来源于stack exchange,提问作者Marco Bevilacqua

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:17:05