通过什么方法,能够在 C# 中重复调用 C++ 中的对象及其函数

yaoxiaofei1220 2021-01-21 08:25:41
各位大牛,请教一个问题

我在 C++ 中定义了一个类 CppTest,希望在 C# 中能够重复调用这个对象:

1.通过 C# 调用,只构造并初始化一次对象;

2.接下来可以在 C# 程序运行过程中,索引到这个对象,并调用其中的方法(Func1,Func2);

如果没有把问题描述清楚,还请留言,如果各位有解决方法,在此先谢过。

由于原代码比较大,下面是简单示意代码:
class CppTest
{
public:
CppTest();
~CppTest();

//以下函数中会用到成员变量(mData1,mData2等)
void Func1();
void Func2();

private:
//大量成员变量
int mData1;
double mData2;
};
...全文
970 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
yifeiyuann 2021-01-29
  • 打赏
  • 举报
回复
写的很好,谢谢分享
丁劲犇 2021-01-27
  • 打赏
  • 举报
回复
这个可以参考很多C库的做法。用C++实现,导出C的接口。 其实就是把实例的创建、调用、销毁全部变为C函数,第一个参数是this指针即可。 uint64 __stdcall mylib_init_instance(XXX) { MyClass * c = new MyClass(XXX); return (uint64) c; } ZZZ __stdcall mylib_call(uint64 handle, YYY) { MyClass * c = (MyClass *) handle; return c->call(YYY); } void __stdcall mylib_free(uint64 handle) { MyClass * c = (MyClass *) handle; delete c; } 导出时候加extern c,并在def文件中列举名字。
ziqi0716 2021-01-27
  • 打赏
  • 举报
回复
引用 16 楼 孤此一木จุ๊บ 的回复:
C++中把Cpptest类封装到一个函数库中,函数库提供void Func1();void Func2()等方法,他们调用Cpptest实例的对应方法. C#中将两个方法导入到一个Helper类中,作为静态函数即可. 也就是说,对象实例化不要让C#接手了,你提供出去的库自己处理好,对外只提供C风格函数方法就行了.
csdn来机器人了?
zerozerg2006 2021-01-27
  • 打赏
  • 举报
回复
这不就是标准的单例模式吗,其他人关于c#调用cpp的方法我不评价,但你们家单例是这么做的?
yaoxiaofei1220 2021-01-27
  • 打赏
  • 举报
回复
引用 21 楼 丁劲犇 的回复:
这个可以参考很多C库的做法。用C++实现,导出C的接口。 其实就是把实例的创建、调用、销毁全部变为C函数,第一个参数是this指针即可。 uint64 __stdcall mylib_init_instance(XXX) { MyClass * c = new MyClass(XXX); return (uint64) c; } ZZZ __stdcall mylib_call(uint64 handle, YYY) { MyClass * c = (MyClass *) handle; return c->call(YYY); } void __stdcall mylib_free(uint64 handle) { MyClass * c = (MyClass *) handle; delete c; } 导出时候加extern c,并在def文件中列举名字。
这也是一个很好的思路,能够满足我上面提的需求,相比用c++/cli也少了中间一层,还在摸索中,感谢分享!
JING11344333 2021-01-26
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
C++中把Cpptest类封装到一个函数库中,函数库提供void Func1();void Func2()等方法,他们调用Cpptest实例的对应方法. C#中将两个方法导入到一个Helper类中,作为静态函数即可. 也就是说,对象实例化不要让C#接手了,你提供出去的库自己处理好,对外只提供C风格函数方法就行了.
yaoxiaofei1220 2021-01-26
  • 打赏
  • 举报
回复
引用 14 楼 翅膀又硬了 的回复:
你问这个是单例模式吗?c++的库给其它语言用,最好是导出 标准C的函数,别用对象这些
不是单例模式,需要多实例,并且需要管理生命周期; 因为对象中会有大量成员变量(包含一些复杂数据结构),如果只导出函数的话,需要每次都传入这些参数;
翅膀又硬了 2021-01-26
  • 打赏
  • 举报
回复
你问这个是单例模式吗?c++的库给其它语言用,最好是导出 标准C的函数,别用对象这些
加油馒头 2021-01-26
  • 打赏
  • 举报
回复
引用 7 楼 wanghui0380 的回复:
有时候,我们也不得不说几句。很多人喊着没有框架,net死了,或者说net没有这个,没有那个,或者追着ABP这种巨无霸 但其实net本身在发展,现在的netcore,net5其实本身就是应用框架,区别与以前的平台框架,语言框架。他现在本身就是类似sping boot的应用框架 所以我们不是需要天天喊着这个没有,那个死了。我们需要内求,而不是天天外求ABP这种巨无霸 废话不多说(对于不想内求的人来说,说多了他们不想听,他们觉着你是BS他们,是对他们这10年工作经验的否定)来看现在的代码
引用
Service.AddScopped 为每个http Web请求创建一个新实例。
我谁便找个所谓asp.net netcore的资料来看。(虽然是aps.net core的资料,其实他的通用的,微软的通用主机( general host)其实是一样的技术) 其实这东西就是你要的,虽然那些人说,这是web,是每个http Web请求创建一个新实例。其实这就是你要的,“为每个单独的object(假如我们把你口中的说的这个object叫做一次请求) 去生成一些只需要初始一次的上下文配置(在这个请求的生存期内他就初始化一次)” 东西就说这么多,能理解的理解,不能理解的我们不强推(这里的状态,你要说他们理解不了的,他们说你是装X。所以俺们不强推,能理解就理解。理解不了我们也不多说)
说这么多,能改变90%企业抛弃NET的事实吗
yaoxiaofei1220 2021-01-25
  • 打赏
  • 举报
回复
引用 2 楼 以专业开发人员为伍 的回复:
使用 c++/CLI 封装。
感谢,这似乎是一个很好的方向,我去研究一下!
yaoxiaofei1220 2021-01-25
  • 打赏
  • 举报
回复
引用 1 楼 ziqi0716 的回复:
C++中把Cpptest类封装到一个函数库中,函数库提供void Func1();void Func2()等方法,他们调用Cpptest实例的对应方法. C#中将两个方法导入到一个Helper类中,作为静态函数即可. 也就是说,对象实例化不要让C#接手了,你提供出去的库自己处理好,对外只提供C风格函数方法就行了.
感谢指教,我可能描述的不是很清楚: 在实际调用过程中,C#中会存在多个对象,与C++中CppTest对象一一对应(多个CppTest对象); 出于对效率考虑,所有CppTest对象希望只实例化一次,之后运行过程中只需要调用这些对象相应函数; 您的建议似乎不能对每个CppTest对象单独管理,不知道我的理解是否正确,期待您的建议?
aaaa152 2021-01-25
  • 打赏
  • 举报
回复
等级 666666
aaaa152 2021-01-25
  • 打赏
  • 举报
回复
等级 666666
aaaa152 2021-01-25
  • 打赏
  • 举报
回复
666666
wanghui0380 2021-01-25
  • 打赏
  • 举报
回复
我个人就经常使用ida pro反编译一些没文档的dll(或者需要研究dll调用了哪些api,以便弄清楚他的实现) 所以如果你要纠结这个没啥必要
wanghui0380 2021-01-25
  • 打赏
  • 举报
回复
额,又讲好不好。 没有好不好,无论托管还是非托管。俺们想看一样看 IDA pro反成类c代码也不是什么新鲜事 至于效率,我们说的是都一样。问题不在效率,问题在于非托管没有gc,你的自己在两端小心处理内存
yaoxiaofei1220 2021-01-25
  • 打赏
  • 举报
回复
引用 4 楼 yaoxiaofei1220 的回复:
[quote=引用 2 楼 以专业开发人员为伍 的回复:]使用 c++/CLI 封装。
感谢,这似乎是一个很好的方向,我去研究一下![/quote] 目前参考以下方法,做了一些改动,初步实现了我的需求; 这是我参考的方法:https://www.cnblogs.com/skyfreedom/p/11783629.html 1.CppTest编译成静态库 CppTest.lib; 2.创建一个 CLR 工程,引用静态库 CppTest.lib,定义一个类InvokeCon,转调CppTest中函数;并生成 InvokeCon.dll; 3.在C#中直接引用 InvokeCon.dll 进行开发; 以下是简单的代码说明:
public ref class InvokeCon
{
public:
	InvokeCon();
	~InvokeCon();

    //以下函数分别转调CppTest中的Func1,Func2
    void Func1();
    void Func2();

private:

    //这是CppTest类型的对象
	CppTest* mCppTest;
};

//在构造InvokeCon对象时,初始化CppTest对象
InvokeCon::InvokeCon()
{
    mData = new CppTest();
}

//销毁CppTest对象
InvokeCon::~InvokeCon()
{
    delete[] mData;
}

void InvokeCon::Func1()
{
    (*mData).Func1();
}

void InvokeCon::Func2()
{
    (*mData).Func2();
}
目前我还有以下疑惑: 1.目前这种方法(将c++代码编译成静态库,然后被c++/cli封装后输出dll文件),是否有被反编译的风险(CppTest直接输出dll文件相比,谁的风险更高,或者更容易被反编译)? 2.这种调用方式效率如何?我初步测试下来,与直接调用dll效率差不多,但是目前缺乏大量测试验证; 3.是否有更优的方案,能够满足以上需求? 感谢您的耐心阅读,如果您有更好的方案,还请不吝指教!
wanghui0380 2021-01-25
  • 打赏
  • 举报
回复
有时候,我们也不得不说几句。很多人喊着没有框架,net死了,或者说net没有这个,没有那个,或者追着ABP这种巨无霸 但其实net本身在发展,现在的netcore,net5其实本身就是应用框架,区别与以前的平台框架,语言框架。他现在本身就是类似sping boot的应用框架 所以我们不是需要天天喊着这个没有,那个死了。我们需要内求,而不是天天外求ABP这种巨无霸 废话不多说(对于不想内求的人来说,说多了他们不想听,他们觉着你是BS他们,是对他们这10年工作经验的否定)来看现在的代码
引用
Service.AddScopped 为每个http Web请求创建一个新实例。
我谁便找个所谓asp.net netcore的资料来看。(虽然是aps.net core的资料,其实他的通用的,微软的通用主机( general host)其实是一样的技术) 其实这东西就是你要的,虽然那些人说,这是web,是每个http Web请求创建一个新实例。其实这就是你要的,“为每个单独的object(假如我们把你口中的说的这个object叫做一次请求) 去生成一些只需要初始一次的上下文配置(在这个请求的生存期内他就初始化一次)” 东西就说这么多,能理解的理解,不能理解的我们不强推(这里的状态,你要说他们理解不了的,他们说你是装X。所以俺们不强推,能理解就理解。理解不了我们也不多说)
wanghui0380 2021-01-25
  • 打赏
  • 举报
回复
xxxManager xxxFactory xxxxBuiler 无所谓他叫啥把,我们也不知道你的应用上下文。对我们来说只是需要这么一个管理上下文,所以你叫Manager管理可以,叫Factory工厂也行,叫Builer构建也行,活着叫CPPBroker经理,CppProxy代理也罢都无所谓 主要是前置一个管理类
加载更多回复(3)

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧