日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

在windows上使用go编译dll文件,供C++调用

發(fā)布時間:2023/11/30 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在windows上使用go编译dll文件,供C++调用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  • C++項目是win32的,所以go的編譯環(huán)境也要改成win32的
  • cmd下,修改環(huán)境變量: set GOARCH=386 set CGO_ENABLED=1 使用go env 查看是否生效

    參考:https://bbs.csdn.net/topics/394513992.
    2. 安裝編譯環(huán)境
    MinGW下載安裝gcc,g++編譯器
    參考:https://blog.csdn.net/cbb944131226/article/details/82940273
    3. 編寫go相關(guān)文件和代碼
    編寫def文件
    比如我要編譯的dll文件,導(dǎo)出函數(shù)為GetIP
    那么編寫一個 godll.def (名字隨便起)
    godll.def

    EXPORTSGetIP package mainimport "C"import ("bytes""crypto/cipher""crypto/des""encoding/hex""fmt""io""math/rand""net/http""strings""time" )func EncryptDES_ECB(src, key string) string {data := []byte(src)keyByte := []byte(key)block, err := des.NewCipher(keyByte)if err != nil {panic(err)}bs := block.BlockSize()//對明文數(shù)據(jù)進行補碼data = PKCS5Padding(data, bs)if len(data)%bs != 0 {panic("Need a multiple of the blocksize")}out := make([]byte, len(data))dst := outfor len(data) > 0 {//對明文按照blocksize進行分塊加密//必要時可以使用go關(guān)鍵字進行并行加密block.Encrypt(dst, data[:bs])data = data[bs:]dst = dst[bs:]}return fmt.Sprintf("%X", out) }func DecryptDES_ECB(src, key string) string {data, err := hex.DecodeString(src)if err != nil {panic(err)}keyByte := []byte(key)block, err := des.NewCipher(keyByte)if err != nil {panic(err)}bs := block.BlockSize()if len(data)%bs != 0 {panic("crypto/cipher: input not full blocks")}out := make([]byte, len(data))dst := outfor len(data) > 0 {block.Decrypt(dst, data[:bs])data = data[bs:]dst = dst[bs:]}out = PKCS5UnPadding(out)return string(out) }func EncryptDES_CBC(src, key string) string {data := []byte(src)keyByte := []byte(key)block, err := des.NewCipher(keyByte )if err != nil {panic(err)}data = PKCS5Padding(data , block.BlockSize())//獲取CBC加密模式iv := keyByte //用密鑰作為向量(不建議這樣使用)mode := cipher.NewCBCEncrypter(block, iv)out := make([]byte, len(data))mode .CryptBlocks(out, data)return fmt.Sprintf("%X", out) }func DecryptDES_CBC(src, key string) string {keyByte := []byte(key)data, err := hex.DecodeString(src)if err != nil {panic(err)}block, err := des.NewCipher(keyByte)if err != nil {panic(err)}iv := keyByte //用密鑰作為向量(不建議這樣使用)mode := cipher.NewCBCDecrypter(block, iv)plaintext := make([]byte, len(data))mode.CryptBlocks(plaintext, data)plaintext = PKCS5UnPadding(plaintext)return string(plaintext) }func PKCS5Padding(ciphertext []byte, blockSize int) []byte {padding := blockSize - len(ciphertext)%blockSizepadtext := bytes.Repeat([]byte{byte(padding)}, padding)return append(ciphertext, padtext...) }func PKCS5UnPadding(origData []byte) []byte {length := len(origData)unpadding := int(origData[length-1])return origData[:(length - unpadding)] }func Get(url string) string {// 超時時間:5秒client := &http.Client{Timeout: 5 * time.Second}resp, err := client.Get(url)defer resp.Body.Close()if err != nil {//panic(err)//fmt.Println(err.Error())return "networkError"}var buffer [512]byteresult := bytes.NewBuffer(nil)for {n, err := resp.Body.Read(buffer[0:])result.Write(buffer[0:n])if err != nil && err == io.EOF {break} else if err != nil {//panic(err)result = bytes.NewBuffer([]byte("networkError"))}}return result.String() }//export GetIP func GetIP(signal int32, domainParam string) *C.char {defer func() {err := recover()if err != nil {//fmt.Println(err)}}()if signal != 8956142 { // 做一下驗證防止被 惡意調(diào)用return C.CString("authError")}key := "xxxxxxxwww"domain := "xxx.com"//domain := "xxxx.cn"enc_str := EncryptDES_ECB(domain, key)httpDnsUrl := "http://xxxxx/d?dn=" + enc_str + "&id=888&ttl=1"respTxt := Get(httpDnsUrl)if respTxt == "networkError" {return C.CString("networkError")}descStr := DecryptDES_ECB(respTxt, key)ips_str := strings.Split(descStr, ",")[0]ips_slice := strings.Split(ips_str, ";")ips_length := len(ips_slice)if ips_length == 1 {return C.CString(ips_slice[0])} else {rand.Seed(time.Now().Unix())index := rand.Intn(ips_length)return C.CString(ips_slice[index])} }func main() {}

    注意:在要導(dǎo)出的函數(shù)(GetIP)上面 寫上 //export GetIP, 還要有main函數(shù)

    實際上我應(yīng)該將 C.CString 創(chuàng)建的內(nèi)存,釋放掉。
    參考:
    https://blog.csdn.net/weixin_34128501/article/details/91709373
    https://blog.csdn.net/liangguangchuan/article/details/52920054
    https://blog.csdn.net/qq_30549833/article/details/86157744

  • 編譯dll文件
  • go build -buildmode=c-archive httpdns.go gcc godll.def httpdns.a -shared -lwinmm -lWs2_32 -o httpdns.dll -Wl,--out-implib,httpdns.lib

    生成 .dll .lib. h文件

  • 用C++調(diào)用, vs2017 (需要用到上面的.dll 和.h)
  • #include "pch.h" #include <iostream> #include <Windows.h> #include <stdio.h> #include "httpdns.h" // dll的頭文件 // 其中 httpdns.h里面的 //typedef __SIZE_TYPE__ GoUintptr; //typedef float _Complex GoComplex64; //typedef double _Complex GoComplex128; 這三行要注釋掉// 根據(jù)httpdns.h 里面導(dǎo)出函數(shù)定義下面類型 typedef char*(*funcPtrGetIP)(GoInt32, GoString); using namespace std; int main() {//加載動態(tài)庫HINSTANCE hInstance = LoadLibrary("httpdns.dll");funcPtrGetIP pFunc_GetIP = (funcPtrGetIP)GetProcAddress(hInstance, "GetIP");int signal = 8956142;char* domain = const_cast<char *>("xxx.com");GoString gostr_domain{ domain,(ptrdiff_t)strlen(domain) };//就是go中的string類型char* ipstr = pFunc_GetIP(signal, gostr_domain);cout << strlen(ipstr) << endl;cout << ipstr << endl;//FreeLibrary(hInstance); //release模式會崩潰,原因未知return 0; }

    ----2020-12-29----
    補充下:
    關(guān)于在go中使用C.String后,內(nèi)存需要釋放的,寫一個釋放內(nèi)存的接口

    /* #include <stdio.h> #include <stdlib.h> */ import "C"//export FreeDecryUserKey func FreeDecryUserKey(pointer *C.char) {fmt.Println("will free pointer ")fmt.Println(pointer)C.free(unsafe.Pointer(pointer))//釋放內(nèi)存 必須引入stdlib.h 標(biāo)準(zhǔn)庫 }

    在Cpp中這樣使用

    #include <iostream> #include <string> #include <Windows.h> #include "aesdecry.h" using namespace std;typedef char*(*funcPtrGetDecryUserKey)(GoString, GoString); typedef void (*funcPtrFreeDecryUserKey)(char*);int main() {std::string user_base64_key = "1a07b51b220c5083ede4903cf0e1da88823e8134eb81b6a78396234a6de8d06de6f94a55d0e8762849ae58c70d436217";HINSTANCE hInstance = LoadLibrary("main.dll");funcPtrGetDecryUserKey pFunc_GetDecryUserKey = (funcPtrGetDecryUserKey)GetProcAddress(hInstance, "GetDecryUserKey");funcPtrFreeDecryUserKey pFunc_FreeDecryUserKey = (funcPtrFreeDecryUserKey)GetProcAddress(hInstance, "FreeDecryUserKey");char* encry_data = const_cast<char *>(user_base64_key.c_str());char* password = const_cast<char *>("aa6e8b08e4db270c");GoString gostr_encry_data{ encry_data,(ptrdiff_t)strlen(encry_data) };//就是go中的string類型GoString gostr_password{ password,(ptrdiff_t)strlen(password) };//就是go中的string類型char* real_user_key = pFunc_GetDecryUserKey(gostr_encry_data, gostr_password);printf("%x\n", real_user_key);printf("%p\n", real_user_key);std::string targetkey = real_user_key;cout << targetkey << endl;pFunc_FreeDecryUserKey(real_user_key); // 釋放掉內(nèi)存cout << targetkey << endl;return 0; } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

    總結(jié)

    以上是生活随笔為你收集整理的在windows上使用go编译dll文件,供C++调用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲一二区 | 欧美v日本 | 啄木乌欧美一区二区三区 | 亚洲青青操 | 影音先锋亚洲成aⅴ人在 | 国产精品黄色大片 | 小镇姑娘1979版 | 狠操av| 深夜网站在线观看 | 天堂在线视频网站 | 12av在线| 国产日韩欧美在线 | 竹菊影视一区二区三区 | 精品热久久 | www.99av| 特级a毛片 | 成人国产欧美 | 日韩欧美卡一卡二 | 国产成人精品一区二区三区 | 亚洲综合情 | 特级做a爰片毛片免费69 | 亚洲精品黄色 | 成人软件在线观看 | 春色av| av导航在线 | av无码久久久久久不卡网站 | 成人三级做爰av | 亚洲综合资源 | 欧美日韩电影一区 | 免费看毛片网站 | 丰满少妇中文字幕 | 日本爱爱免费视频 | 欧美va亚洲va | 久久久视频在线 | 免费视频毛片 | 台湾黄色网址 | 中文字幕亚洲一区二区三区五十路 | 国产亚洲久久 | 欧美日韩国产一级片 | 精品少妇人妻av免费久久久 | 国产一区二区三区在线观看 | 精品免费囯产一区二区三区 | 中文字幕资源网 | 91香蕉视频黄 | 在线看91| 都市激情自拍偷拍 | 特黄特色免费视频 | 找av导航| 亚洲性片 | 日本高清视频免费观看 | 国产肥老妇视频 | 一区二区成人在线观看 | 国产乱妇4p交换乱免费视频 | 99爱爱视频 | 日本美女黄视频 | 亚洲视频免费 | 奇米激情| 麻豆传媒网页 | 中文精品无码中文字幕无码专区 | 欧美乱做爰xxxⅹ久久久 | 亚洲天堂一区 | 亚洲天堂男人的天堂 | 国产精品一区二区免费在线观看 | 国产免费av观看 | 91一区二区三区在线 | 在线观看一二三区 | 亚洲黄色小说视频 | 久久久www | 天天躁日日躁狠狠躁免费麻豆 | 国产精品传媒 | 亚洲v欧美| 成人做受视频试看60秒 | 欧美色xxxx| 黄色高清在线观看 | 国产精品久久欧美久久一区 | 亚洲午夜视频 | 男男巨肉啪啪动漫3d | 亚洲国产精品自拍视频 | av看片资源 | 天天操天天操天天射 | 日韩欧美的一区二区 | 人妻精品无码一区二区 | 亚洲综合影院 | 国产一区二区在 | 亚洲涩综合 | 国产精品9 | 黄色片免费观看视频 | 五月天中文字幕 | 成年人在线网站 | eeuss鲁丝片一区二区三区 | 国产一级视频在线观看 | 姝姝窝人体www聚色窝 | 蜜桃精品久久久久久久免费影院 | xxxx日本高清 | 天狂传说之巴啦啦小魔仙 | 日韩色影院 | 可以看毛片的网站 | 一级片少妇 | 欧美熟妇久久久久 |