golang調用c++的dll庫檔案

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
最近使用golang調用c++的dll庫檔案,簡單瞭解了一下,特作此筆記:
一、DLL 的編製與具體的程式設計語言及編譯器無關
只要遵循約定的 DLL 介面規範和調用方式,用各種語言編寫的 DLL 都可以相互調用。譬如 Windows 提供的系統 DLL (其中包括了 Windows 的 API ),在任何開發環境中都能被調用,不在乎其是 Visual Basic 、 Visual C++ 還是 Delphi
二、dll檔案裡面需要被其他程式訪問的函數必須匯出,有2種方法
源檔案如下:
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 DllTestDefEXPORTSadd @ 1;匯出其中的add函數,並指定add函數的序號為1;sub @ 2

添加檔案到項目屬性裡面的Linker/input裡面

三、在golang裡面使用,也有3種方法

注意的是golang由於資料類型和c++的不一致,在需要傳參的時候需要把所有的參數都轉換成uintptr指標類型,而且轉換的過程需要藉助unsafe.Pointer指標

package mainimport (    "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,        2,        IntPtr(a),        IntPtr(b),        0)    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(4, 5)    DllTestDef_add(4, 5)    DllTestDef_add2(4, 5)}

所有源碼下載

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.