C#与C++代码互相调用
来源:互联网 发布:手机网络助手下载 编辑:程序博客网 时间:2024/05/20 05:26
今天在项目中看到C:\WINDOWS\Microsoft.NET\Framework\v...\REGASM.exe /regfile:xxx.reg xxx.dll,注册COM组件。
开始不明白为啥要注册COM组件,c#自己调自己的dll用不着这样啊,网上查看大都是讲如何注册COM组件。
经过不懈网上游荡,原来注册COM组件是给其他语言调用的,因为c#程序是托管代码,所以和其他非托管代码有所差异。
查就查到底,继续在网上查资料,把这块东西系统的整理下:
1.c#引用托管程序集-----直接引用
2.c#引用非托管代码-----通过P/Invoke(Plateform Invoke)机制调用dll函数
C代码和C++代码编译方式不同,C语言编译出来的函数入口和函数名一样,但C++编译出来的入口和函数名不一样,这是因为有重载的关系;这时,如果是C++代码,要么在函数名前加extern "C" rvalue function(param...),要么在编译出来的dll用dumpbin类似工具反编译出来函数入口EntryPoint
[DllImport("user32.dll", CharSet = CharSet.Auto)]private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
动态调用
public static class NativeMethod { [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")] public static extern int LoadLibrary( [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName); [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")] public static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")] public static extern bool FreeLibrary(int hModule); }
static void Main(string[] args) { //1.load c++ dll int hModule = NativeMethod.LoadLibrary(@"c:/CppDemo.dll"); if (hModule == 0) return; IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "MyDelegate"); MyDelegate myDele = (MyDelegate)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(MyDelegate)); Console.WriteLine(myDele(1,2)); }
/// <summary> /// 函数指针 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> delegate int MyDelegate(int a, int b);
3. clr c++调用c#dll
设置项目属性-->配置属性-->常规-->公共语言运行时支持-->公共语言运行时支持(clr)
#using "../debug/xx.dll"using namespace xxx;然后按照托管c++/clr的语法:托管对象使用^……
4.非托管c++调用c#dll
1)用c#写dll
写接口和实现类,贴上GUID特性标签(工具->创建GUID->选择5->复制),Properties下的AssemblyInfo.cs中ComVisible为true
2)注册dll为COM组件
如果在本机开发,在属性->生成->为COM互操作注册即能完成注册功能或应用程序->程序集信息
但是要在别的机子上使用那就需要用REGASM.exe来注册
C:\WINDOWS\Microsoft.NET\Framework\v...\REGASM.exe /regfile:xxx.reg xxx.dll然后运行xxx.reg注册该COM组件
3)使用
namespace ComInteropDemo { //接口声明 [Guid("7103C10A-2072-49fc-AD61-475BEE1C5FBB")] public interface ComInteropInterface { [DispId(1)] int Add(int a, int b); [DispId(2)] int Minus(int a, int b); } //对于实现类的声明 [Guid("87796E96-EC28-4570-90C3-A395F4F4A7D6")] [ClassInterface(ClassInterfaceType.None)] public class ComInterop : ServicedComponent, ComInteropInterface { public ComInterop() { } public int Add(int a, int b) { return a + b; } public int Minus(int a, int b) { return a - b; } } }
#include "stdafx.h" #include <iostream> using namespace std; #import "..//Debug//ComInteropDemo.tlb" //路径一定要正确 int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr; //ComInteropDemo::ComInterop *p; CoInitialize ( NULL ); //创建智能指针ComInteropDemo::ComInteropInterface ComInteropDemo::ComInteropInterfacePtr ptr; //创建实例 hr = ptr.CreateInstance(__uuidof (ComInteropDemo::ComInterop)); if(hr == S_OK) { cout << ptr->Add (1.0, 2.0); } CoUninitialize (); return 0; }
- C#与C++代码互相调用
- C# 调用C++, C++与C#互相调用
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用二(C++调用C#代码)
- C#与JavaScript互相调用
- C#与JavaScript互相调用
- C与C++互相调用
- c与c++互相调用
- c++与c互相调用
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- 怎样去了解软件系统周边影响因素
- thinkphp框架中jquery $.post()用法详解
- iOS __block和__weak的区别
- pandas将类别属性转化为数值属性的方法
- kaggle Code :House Prices: Advanced Regression Techniques 回归
- C#与C++代码互相调用
- 二叉搜索树
- 再读SIFT理论及源码
- HDU 1847(Good Luck in CET-4 Everybody!) 巴什博弈 Java
- 单调队列入门
- 查找——线性索引查找
- unix 02
- Hbase数据库的一些基础知识
- 【AndroidManifest.xml详解】Manifest属性之versionCode,versionName