编写C++非托管DLL以及在.NET托管中调用

分类:.Net知识问答| 发布:camnprbubuol| 查看: | 发表时间:2011/5/14



编写C++非托管DLL以及在.NET托管中调用

 

新建项目,来到Win32,点击Win32项目

输入名称MyVC点击确定。

应用程序类型,勾选DLL,点击完成。

 

 

MyVC.cpp

 

#include "stdafx.h"

#include <stdio.h>

 

extern "C" __declspec(dllexportint Max(int a,int b)

{

         return a>b?a:b;

}

extern "C" __declspec(dllexportint Min(int a,int b)

{

         return a>b?b:a;

}

 

//此示例来自CSDN

extern "C" __declspec(dllexportvoid GetName(char* buffer, int* size)

{

    printf("before copy the length is:%d\n", *size);//写数据前buffer的容量

    char temp[] = "hello,world";

    strcpy(buffer,temp); //模拟写数据

    printf("OK, string is:%s\n", buffer);

    *size = (int)strlen(temp);

    printf("after copy the length is:%d\n", *size);//写数据后buffer的容量

}

 

 

其中 extern   "C "   生成的dll,不会分解函数名

 

其中 __declspec(dllexport) 导出dll为其他程序调用

 

 

好了,生成即可。

 

生成的dll放到 C:\WINDOWS\system32  目录下面,这样不需要指定路径。

或者不放在此文件夹下面,那直接指定完整的目录也可以。

 

 

 

嗯,现在在.NET中调用它

 

using System.Runtime.InteropServices;

 

[DllImport(@"D:\MyVC\Debug\MyVC.dll")]

        public extern static void GetName(StringBuilder sb, IntPtr length);

        [DllImport(@"D:\MyVC\Debug\MyVC.dll")]

        public extern static int Max(int a, int b);

        [DllImport(@"D:\MyVC\Debug\MyVC.dll")]

        public extern static int Min(int a, int b);

 

        static void Main(string[] args)

        {

            StringBuilder sb = new StringBuilder(256);

            IntPtr ptr = Marshal.AllocHGlobal(sizeof(int));//申请一个整数指针

            Marshal.WriteInt32(ptr, sb.Capacity);//给指针内容赋初值为缓冲区容量

 

            GetName(sb, ptr);

 

            Marshal.FreeHGlobal(ptr);

 

            Console.WriteLine(Max(22, 106).ToString()); //106

            Console.WriteLine(Min(22, 106).ToString()); //22

            Console.Read();

        }

 

 

 

 

我在制作过程中遇到的一些问题:

 

无法加载 DLLMyVC.dll参数不正确。 (异常来自 HRESULT:0x80070057 (E_INVALIDARG))

清理解决方案再生成

 

 

 

 PInvoke 函数“ConsoleApplication1!ConsoleApplication1.Program::Max”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

 

点击C++项目属性,来到配置属性下面的C/C++,点击高级

在右边的“调用约定”里,选择 __stdcall (/Gz)

 

 

OK,有什么不明白的地方欢迎留言。

365据说看到好文章不转的人,服务器容易宕机
原创文章如转载,请注明:转载自郑州网建-前端开发 http://camnpr.com/
本文链接:http://camnpr.com/net-wiki/324.html