golang调用c++的dll库文件
最近使用golang调用c++的dll库文件,简单了解了一下,特作此笔记:
一、DLL 的编制与具体的编程语言及编译器无关 dll分com的dll和动态dll,
Com组件dll:不管是何种语言写的都可以调用,但com分很多种。比如而php只能调用com的dll的特定的几种、不能直接调用动态dll,要使用第三方的dll文件dynwrap.dll或者编译PHP扩展来迂回调用
动态dll:只要遵循约定的 DLL 接口规范和调用方式,用各种语言编写的 DLL 都可以相互调用。譬如 Windows 提供的系统 DLL (其中包括了 Windows 的 API ),在任何开发环境中都能被调用,不在乎其是 Visual Basic 、 Visual C++ 还是 Delphi
二、动态dll文件里面需要被其他程序访问的函数必须导出,有2种方法(c++,其他语言不清楚)
源文件如下:
DllTestDef.h
#ifndef DLLTESTDEF_H
#define DLLTESTDEF_H
int add(int x, int y);
#endif
DllTestDef.cpp
#include "DllTestDef.h"
int add(int x, int y)
{
return x + y;
}
2.1、通过在.h头文件里面为函数添加 __declspec(dllexport),例如:
_declspec(dllexport) int add(int a, int b);
说明:此方式下,如果调用该dll的是一个c++程序(同一个编译器的版本)是没有问题的。但是如果是一个其它语言的程序(如C#、VB),则会出错
因为VC++编译器对于__declspec(dllexport)声明的函数会进行名称转换,如上面的函数会转换为Add@0,这样你在VB中必须这样声明:
Declare Function Add Lib "DLLTestDef.dll" Alias "Add@0" () As Long
@后面的数由于参数类型不同而可能不同。这显然不太方便。
为了解决这一问题,我们往往在函数前面再加一个extern "C",使用C方式的函数命名规则。所以为了大范围的使用我们基本申明都如下:
extern "C" _declspec(dllexport) int add(int a, int b);
DllTestDef.h
#ifndef DLLTESTDEF_H
#define DLLTESTDEF_H
extern "C" __declspec(dllexport) int add(int x, int y);
#endif
DllTestDef.cpp同源文件
2.2、使用.def文件,为了简化2.1的那一长串代码,MS引入了def文件方便我们操作。
DllTestDef.h同源文件
DllTestDef.cpp同源文件
DllTestDef.def
LIBRARY DllTestDef
EXPORTS
add @
;导出其中的add函数,并指定add函数的序号为1
;sub @
添加文件到项目属性里面的Linker/input里面
三、在golang里面使用动态dll,也有3种方法 注意的是golang由于数据类型和c++的不一致,在需要传参的时候需要把所有的参数都转换成uintptr指针类型,而且转换的过程需要借助unsafe.Pointer指针
package main import (
"fmt"
"syscall"
"unsafe"
) func IntPtr(n int) uintptr {
return uintptr(n)
} func StrPtr(s string) uintptr {
return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s)))
}
func Lib_add(a, b int) {
lib := syscall.NewLazyDLL("lib.dll")
fmt.Println("dll:", lib.Name)
add := lib.NewProc("add")
fmt.Println("+++++++NewProc:", add, "+++++++") ret, _, err := add.Call(IntPtr(a), IntPtr(b))
if err != nil {
fmt.Println("lib.dll运算结果为:", ret)
} } func DllTestDef_add(a, b int) {
DllTestDef, _ := syscall.LoadLibrary("DllTestDef.dll")
fmt.Println("+++++++syscall.LoadLibrary:", DllTestDef, "+++++++")
defer syscall.FreeLibrary(DllTestDef)
add, err := syscall.GetProcAddress(DllTestDef, "add")
fmt.Println("GetProcAddress", add) ret, _, err := syscall.Syscall(add,
,
IntPtr(a),
IntPtr(b),
)
if err != nil {
fmt.Println("DllTestDef.dll运算结果为:", ret)
} } func DllTestDef_add2(a, b int) {
DllTestDef := syscall.MustLoadDLL("DllTestDef.dll")
add := DllTestDef.MustFindProc("add") fmt.Println("+++++++MustFindProc:", add, "+++++++")
ret, _, err := add.Call(IntPtr(a), IntPtr(b))
if err != nil {
fmt.Println("DllTestDef的运算结果为:", ret)
}
} func main() {
Lib_add(, )
DllTestDef_add(, )
DllTestDef_add2(, )
}
golang调用c++的dll库文件的更多相关文章
- VS2015 建立C++ dll库文件
最近在写一个图片处理,正好用到C++封装DLL给C#调用,一下是总结: 建立一个C++的Win32DLL,这里要注意选择"Export symbols"导出符号.点击完成. 如 ...
- Visual Studio 项目中添加include, lib, dll库文件(*.h,*.lib,*.dll)
应用程序使用外部库时需要进行加载,两种库的加载本质上都是一样:提供功能和功能的定义.vs2005 c++ 项目设置外部库方法如下: 1. 添加编译所需要(依赖)的 lib 文件 在“项目-&g ...
- VS编译后直接复制DLL库文件到其他目录下
项目目录:SourceCode\公共组件\KApiClient\ 要复制的目的目录: SourceCode\公共组件\DllLibrary\ApiClient 则在项目 KApiClient下添加如下 ...
- golang调用c动态库
golang调用c动态库 简介 golang调用c语言动态库,动态方式调用,可指定动态库路径,无需系统目录下 核心技术点 封装c动态库 go语言调用c代码 实例代码 封装c动态库 头文件 test_s ...
- LabView调用C#混合模式dll
在一些特定要求下,我们的C#可能需要制作dll给LabView进行调用,并且我们不能够保证C#的程序是完全自己写而不调用第三方的dll库.很多时候我们需要使用诸如Sqlite.Net.AForge.N ...
- linux下编译自己的库文件实践
有了我传的那个资料,这个就没什么用了,那个太经典了,这个就是记录我自己的实践.:-) linux下文件的类型是不依赖于其后缀名的,但一般来讲:.o,是目标文件,相当于windows中的.obj文件.s ...
- LoadLibrary方法加载运行DLL库
最近和另一家公司对接,要求用对方提供的测试程序测试我们做的DLL. 接到对方的测试程序,发现和我们以前调用DLL的方式不太一样.但我稍微看了一会代码也看懂其意思了,一天搞定了. 但其中也遇到些小困惑, ...
- 程序中引入库文件的头文件 编译时并不需要显示的用gcc去链接他的库文件 why?
拿一个苹果系统下的c文件为例: testArr.c #include <stdio.h> int main() { , , , , }; printf(]); } 当我们编译的时候 一般 ...
- 012.CI4框架CodeIgniter, 加载并调用自己的Libraries库
01. 在Libraries目录创建一个Mylib文件,内容是一个简单的类 <?php namespace App\Controllers; class Home extends BaseCon ...
随机推荐
- mount: /dev/sdb1 already mounted or /mnt/hdb busy 导致NameNode无法启动
最近,公司由于断电导致的服务器关机,等到来电了,重启集群发现Namenode无法启动,查看原因是由于无法加在faimage文件,在查看一下Namenode的磁盘挂在情况(df -h命令查看),发现磁盘 ...
- 2014年7月份第2周51Aspx源码发布详情
体育馆综合会员管理系统源码 2014-7-11 [VS2010]功能介绍:本系统适用于羽毛球馆,台球馆,乒乓球馆,棋牌室,篮球馆等综合体育馆,可同时使用.本系统功能非常强大,包含体育馆内餐厅,超 ...
- 按月统计tcode和report使用次数的工具
执行report,输入要查询的日期和user, 工具会按照使用次数从高到低列出输入日期所在的月份内所有该user 曾经使用过的tcode 和report list: REPORT zusertcode ...
- android SDK 离线下载更新
http://blog.csdn.net/harvic880925/article/details/37913801 前言:在公司配置eclipse做android开发,真是烦死了,不知公司做了哪门子 ...
- Best Coder Round#25 1003 树的非递归访问
虽然官方解释是这题目里的树看作无向无环图,从答案来看还是在“以1作为根节点”这一前提下进行的,这棵树搭建好以后,从叶节点开始访问,一直推到根节点即可——很像动态规划的“自底向上”. 但这棵树的搭建堪忧 ...
- 码农带你区分String类型的"=="和equals()
大家玩csdn也可以关注我的博客额http://blog.csdn.net/wujiandong25253344 情形一: String s1= new String("hello" ...
- javaweb学习总结 servlet开发(一)
转载:http://www.cnblogs.com/xdp-gacl/p/3760336.html 这里主要是将其加入自己的理解过一遍. 这里的代码全在eclipse java ee中执行的. 一.s ...
- PID算法学习记录
最近做项目需要用到PID算法,这个本来是我的专业(控制理论与控制工程),可是我好像是把这个东西全部还给老师了. 没办法,只好抽时间来学习了. 先占个座,后续将持续更新!
- oracle行转列,decode 等用法
DECODE()函数,它将输入数值与函数中的参数列表相比较,根据输入值返回一个对应值.函数的参数列表是由若干数值及其对应结果值组成的若干序偶形式.当然,如果未能与任何一个实参序偶匹配成功,则函数也有默 ...
- Koala-Sass编译
1.安装: 下载地址:http://koala-app.com/ 安装好了之后,打开界面如下: 2.简单配置: 打开设置: 3.设置中文: 打开安装目录下的文件:C:\Program Files (x ...