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

如何通过CLI/C++包装器从C#调用含byte*、int*参数的C++函数

解决C#通过CLI/C包装器调用含int*参数的C函数问题

首先要修正原生C++函数的逻辑错误:原IncrementBy2函数直接对指针地址做加法,并没有修改指针指向的实际数值,必须解引用指针后再操作。

1. 修复原生C++类代码

class UNMANAGEDLIB_API CUnmanagedLib {
public:
    CUnmanagedLib(void);
public: 
    void PrintMessage(char* message)
    {
        CString StrMessage = message;
        MessageBox(NULL, StrMessage, L"Test Message", MB_OK);
    }
public:
    void IncrementBy2(int* myval)
    {
        // 解引用指针,修改实际指向的数值
        *myval += 2;
    }
};

2. 修改CLI/C++包装器类

CLI包装器中不能直接用int*作为对外暴露的参数,应该使用CLI的跟踪引用int%,对应C#的ref关键字,这样无需启用unsafe模式就能安全传递引用:

#pragma once
#include "..\UnmanagedLib\UnmanagedLib.h"
using namespace System;
using namespace System::Runtime::InteropServices;
namespace NativeCodeWrapper {
    public ref class Class1
    {
    public: 
        void SendMessageWrapper(String^ strMessage)
        {
            CUnmanagedLib instance;
            char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(strMessage);
            instance.PrintMessage(str2);
            // 释放Marshal分配的非托管内存,避免泄漏
            Marshal::FreeHGlobal(IntPtr(str2));
        }

    public: 
        void IncrementBy2Wrapper(int% myval)
        {
            CUnmanagedLib instance;
            // 将跟踪引用转换为非托管指针传递给原生函数
            int* valPtr = &myval;
            instance.IncrementBy2(valPtr);
        }
    };
}

注:原SendMessageWrapper存在内存泄漏,需添加Marshal::FreeHGlobal释放分配的内存。

3. C#调用代码修改

在C#中使用ref关键字传递参数,即可让原生函数修改C#变量的实际值:

NativeCodeWrapper.Class1 cls = new NativeCodeWrapper.Class1();
// 正常调用字符串参数的函数
cls.SendMessageWrapper("Hello");

int i = 0;
// 使用ref关键字传递参数,让原生函数修改i的值
cls.IncrementBy2Wrapper(ref i);
// 此时i的值会被修改为2
Console.WriteLine(i);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:57:27