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;     }
原创粉丝点击