使用PInvoke实现C#调用非托管C代码DLL库
来源:互联网 发布:软件所应明生怎样 编辑:程序博客网 时间:2024/06/05 04:04
1、使用VS2015 C++编写C语言动态链接库DLL
2、在VS中新建一个DLL工程,选择文件-新建工程,项目类型选 择Win32 终端应用程序
3、在工程序中添加test.cpp源文件。编写测试程序如下:
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
int abc(int a, int b)
{
return a*b;
}
__declspec(dllexport) int sum(int a, int b)
{
int c;
c = abc(a, b);
return c;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
4、编译生成test.dll
5、新建一个C#窗体程序,如代码如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("osipDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int sum(int a, int b);
private void button1_Click(object sender, EventArgs e)
{
int i;
string ser;
i = sum(5, 7);
ser = string.Format(“{0}", i);
textBox1.Text = (ser);
}
}
}
6、运行成功,得值35
7、问题:
Invoke调用导致堆栈不对称 c#调用C++win32非托管dll的问题深度分析
解决办法:
1、在c#中函数声明处改一个参数,[DllImport("xx.dll", EntryPoint=“xxFunction”,CallingConvention = CallingConvention.Cdecl)]调用时不变
2、在c++代码中改对应的c++函数参数从
extern“C” _declspec(dllexport) void xxFunction()改成
extern“C” _declspec(dllexport) void __stdcall xxFunction()
问题分析:
在c++WIN32程序中有三种callingconvention(呼叫约定):__cdecl, __stdcall, __fastcall默认为__cdecl,而c#中默认为CallingConvention=CallingConvention.Winapi,两个平台呼叫约定不一致,所以会出现提示的不匹配错误。
__cdecl为调用函数即C#中清理堆栈中保存的参数。参数的大小不确定时用这个,比如string
__stdcall对应c#中CallingConvention=CallingConvention.Winapi,它由c++中函数自动清理。
Win32 calling convention(呼叫约定)的三种约定具体分析见http://www.cnblogs.com/super119/archive/2011/04/10/2011304.html
http://www.cnblogs.com/dust/articles/1190641.html。- 使用PInvoke实现C#调用非托管C代码DLL库
- 使用平台调用(PInvoke)实现C#调用非托管C++代码
- C#调用c代码生成的dll,报PInvoke 签名与非托管的目标签名不匹配
- PInvoke调用导致堆栈不对称 c#调用C++win32非托管dll的问题深度分析
- PInvoke调用导致堆栈不对称 c#调用C++win32非托管dll的问题深度分析
- PInvoke调用导致堆栈不对称 c#调用C++win32非托管dll的问题深度分析
- C#调用C DLL:调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配
- 使用C#调用非托管DLL函数
- C#【异常处理】调用dll。GetProcAddress 托管的 PInvoke 签名与非托管的目标签名不匹配?
- C#调用非托管DLL
- C#调用非托管DLL
- C#调用非托管Dll
- C#调用非托管DLL
- C#调用非托管DLL
- C#调用非托管DLL
- C#调用非托管dll
- C#调用非托管DLL
- [C#/C++]C#调用非托管DLL的APIs
- 编程异常(不断更新)
- 第一章 Maven简介
- Codeforces Round #443 (Div. 1) D. Magic Breeding 状态压缩,bitset优化
- JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
- JSP笔记
- 使用PInvoke实现C#调用非托管C代码DLL库
- 记录一些前端面试题01
- 线程本地存储—ThreadLocal,map实现
- maven仓库阿里云镜像配置
- 串口调试命令
- 最速下降法的C语言实现
- ubuntu16.04安装TimescaleDB
- phpmyadmin登录不进去
- 关于iOS 插入日历功能以报错Error Domain=EKErrorDomain Code=1 "尚未设定日历。" UserInfo={NSLocalizedDescription=尚未设定日历。}