1. 程式人生 > >CGO 之 Dll呼叫

CGO 之 Dll呼叫

生成的dll庫程式碼

// GoDll.cpp : 定義 DLL 應用程式的匯出函式。
//

#include "stdafx.h"
#include <iostream>
#include <cstdint>

void  __stdcall void_R0()
{
	std::cout << __FUNCTION__ << std::endl;
}


void  __stdcall void_R1(const char* name)
{
	std::cout << __FUNCTION__ << " ----> " << name << std::endl;
}


void  __stdcall void_R2(const char*name ,char **outName)
{
	std::string _name = "HintSoft 新浩藝-";
	_name += name;
	strcpy(*outName,_name.c_str());
}


uint8_t __stdcall uint8_R1(char** outJson)
{
	*outJson = new char[256];
	memset(*outJson,0,256);
	strcpy(*outJson,"Hello -> 你被騙了,這裡沒有Json,只有中文");
	return 1;
}

void __stdcall uint8_R1_free(char** outJson)
{
	if(outJson == 0) return;

	if(*outJson == 0) return;

	delete [](*outJson);
	*outJson = nullptr;
}

typedef void (*CallBackFunType)(const char * in);
void setCallBackFun(CallBackFunType func)
{
	if(!func)
	{
		std::cout << __FUNCTION__ << "   NULL ptr" << std::endl;
	}

	func("hello CallBackFuncType  ---- setCallBackFun");
}

匯出函式def
EXPORTS
void_R0						@1
void_R1						@2
void_R2						@3
uint8_R1					@4
uint8_R1_free				        @5
setCallBackFun				        @6

go呼叫測試
package main

import (
	"fmt"
	"syscall"
	"unsafe"
)

/*
#include <stdio.h>   // 如果要呼叫C.free 一定要在些包含對應的標頭檔案
#include <stdlib.h>

// 以下兩種方式任選其一
void CallBackFun( char* in);
//void CallBackFun( char* in)
//{
//	printf("%s\r\n",in);
//}


*/
import "C"

// export 必須要
//export CallBackFun
func CallBackFun(in *C.char) {
	fmt.Print(C.GoString(in))
}

func main() {
	fmt.Println("---------------------------------------------------------------")

	handle, err := syscall.LoadDLL("GoDll.dll")
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	fmt.Println(handle.Handle)
	fmt.Println(handle.Name)

	void_R0, err := handle.FindProc("void_R0")
	if err != nil {
		fmt.Println("void_R0 不存在", err.Error())
		return
	}

	void_R1, err := handle.FindProc("void_R1")
	if err != nil {
		fmt.Println("void_R1 不存在", err.Error())
		return
	}

	void_R2, err := handle.FindProc("void_R2")
	if err != nil {
		fmt.Println("void_R2 不存在", err.Error())
		return
	}

	uint8_R1, err := handle.FindProc("uint8_R1")
	if err != nil {
		fmt.Println("uint8_R1 不存在", err.Error())
		return
	}

	uint8_R1_free, err := handle.FindProc("uint8_R1_free")
	if err != nil {
		fmt.Println("uint8_R1_free 不存在", err.Error())
		return
	}

	setCallBackFun, err := handle.FindProc("setCallBackFun")
	if err != nil {
		fmt.Println("setCallBackFun 不存在", err.Error())
		return
	}

	fmt.Println("--------------------------函式載入成功-------------------------")
	// -------------------------------------------------------------------------
	fmt.Println("---- void_R0")
	fmt.Println(void_R0.Addr())
	void_R0.Call()
	// -------------------------------------------------------------------------
	fmt.Println("\r\n\r\n---- void_R1")
	fmt.Println(void_R1.Addr())
	name := C.CString("li_jian_xing")
	void_R1.Call((uintptr)(unsafe.Pointer(name)))
	C.free(unsafe.Pointer(name))
	// -------------------------------------------------------------------------
	// 建立陣列,傳入char** 取出C函式中的資料
	fmt.Println("\r\n\r\n---- void_R2")
	fmt.Println(void_R2.Addr())
	arg := make([]C.char, 1024)
	name = C.CString("li_jian_xing")
	void_R2.Call((uintptr)(unsafe.Pointer(name)), (uintptr)(unsafe.Pointer((&arg))))
	C.free(unsafe.Pointer(name))
	fmt.Println(C.GoString(&arg[0]))
	// -------------------------------------------------------------------------
	// 傳入char** 取出C函式分配的記憶體,處理完再釋放
	fmt.Println("\r\n\r\n---- uint8_R1")
	fmt.Println(uint8_R1.Addr())
	var argc *C.char
	uint8_R1.Call((uintptr)(unsafe.Pointer(&argc)))
	fmt.Println(C.GoString(argc))
	uint8_R1_free.Call((uintptr)(unsafe.Pointer(&argc)))
	// -------------------------------------------------------------------------
	// 向dll 函式設定回撥
	fmt.Println("\r\n\r\n---- setCallBackFun")
	fmt.Println(setCallBackFun.Addr())

	setCallBackFun.Call((uintptr)(unsafe.Pointer(C.CallBackFun)))

	handle.Release() // 釋放dll 控制代碼

}



相關推薦

CGO Dll呼叫

生成的dll庫程式碼 // GoDll.cpp : 定義 DLL 應用程式的匯出函式。 // #include "stdafx.h" #include <iostream> #include <cstdint> void __stdcall

ATL--建立簡單的ATLdll工程,新增類和類的介面並在MFC中呼叫

資源打包 開發環境 Windows Server 2012  VS2010 Sp1 番茄助手 建立ATL簡單dll工程 1、開啟VS2010,新建ATL COM 專案,步驟:“檔案” <-->“新建” <-->“專案”,選擇“Visual C++”

微服務優化非同步呼叫

微服務優化之非同步呼叫 原文連結 前一節《微服務優化之並行》,主要從並行的角度來提高微服務的響應時間,本節講一下微服務優化之非同步呼叫。非同步的前提是對依賴的RPC介面呼叫,不需要關心其執行結果,對資料沒有強一致性要求,只要能夠達到最終一致性就好。 該種情況下,實現方式一般有兩種: 第一

微服務優化並行呼叫

微服務優化之並行呼叫 原文連結 網際網路產品隨著使用者的增加,系統對服務的高效能、高可用、可伸縮、可擴充套件的支援,大都採用分散式RPC框架。然而隨著業務的增加,系統越來越多,系統之間的呼叫也越來越複雜,原本一個系統中一次請求就可以完成的工作,現在可能被分散在多個系統中,一次請求需要多個系統

.net Reactordll檔案反編譯混淆

.net Reactor之dll檔案反編譯混淆 .net Reactor的主要功能: 1.是對dll檔案、exe檔案進行反編譯混淆 2.對dll進行內部加鎖,限制其使用的固定機器、固定時間、部署次數 2.建立證書檔案,用證書管理其限制的機器、時間、部署次數 頁面: 混淆方法: 1.在file

ReactsetState呼叫unmount元件報警告

最近公司比較忙,所以更新進度比較慢,一是因為要梳理以前的程式碼,二是因為趕進度!!! 這個問題也是機緣巧合碰到了,正趕上這周公司網路無緣無故抽風(很慢),然後那天在除錯程式碼的時候忽然發現瀏覽器報了一個這樣的Warning: warn.png   其實從字面上也大概可以瞭

Go語言反射反射呼叫

文章目錄 1 概述 2 建立例項 3 呼叫函式 4 呼叫方法 1 概述 利用反射,不僅可以獲取資訊,還可以建立例項,執行函式和方法。就是反射代理執行。 2 建立例項 建立例項的前提是具有

C# 呼叫WebService的3種方式 :直接呼叫、根據wsdl生成webservice的.cs檔案及生成dll呼叫、動態呼叫

1.直接呼叫 已知webservice路徑,則可以直接 新增服務引用--高階--新增web引用 直接輸入webservice URL。這個比較常見也很簡單 即有完整的webservice檔案目錄如下圖所示, 也可以在本地IIS根據webservice檔案目錄新發佈一個webserv

SpringCloud服務呼叫(Ribbon)

業務場景 訂單服務呼叫商品服務叢集,進行偽下單功能開發,使用Ribbon實現訂單呼叫商品服務。 思路:1.建立訂單服務2.編寫偽下單介面a.呼叫商品服務獲取商品資訊(Ribbon呼叫服務)b.根據商品資訊,訂單介面返回訂單詳情資訊 呼叫邏輯圖如下: 實現訂單服務專案 訂單服務專案通過Spring

SpringCloud服務呼叫(feign)

前言 前一篇介紹了使用Ribbon的RestTemplate進行服務呼叫的使用方式。除了這種方式進行服務呼叫以外還可以通過Feign進行呼叫,本篇文章就是簡單介紹一下如何使用Feign進行服務呼叫。根據前一篇文章所用專案進行修改。 Feign使用流程 1.pom檔案引入依賴 <!

微服務服務呼叫與安全控制

轉載本文需註明出處:EAWorld,違者必究。   引言: 近年來,大多數企業IT軟體均在向微服務架構轉型,由於微服務架構採用了更細粒度的分散式拆分,對於服務呼叫安全方面的問題更復雜,更需要重視,需要整體的系統化解決方案。本文將分享普元EOS8.0版本的服務呼叫安

dll呼叫的理解

0x00:dll和lib及其區別 靜態庫:在連結步驟中,聯結器將從庫檔案取得所需的程式碼,複製到生成的可執行檔案中,這種庫稱為靜態庫,其特點是可執行檔案中包含了庫程式碼的一份完整拷貝;缺點就是被多次使用就會有多份冗餘拷貝。即靜態庫中的指令都全部被直接包含在最終生成的 EXE 檔案中了

Dubbo原始碼解析consumer呼叫

閱讀須知 dubbo版本:2.6.0 spring版本:4.3.8 文章中使用/* */註釋的方法會做深入分析 正文 在分析consumer初始化時,我們看到了關聯服務引用建立代理的過程,最終會呼叫JavassistProxyFactory的getP

VS2010 C#面板控制元件IrisSkin4.dll呼叫樣例

下載連結: https://download.csdn.net/download/kucoffee12/10800692 最近做一些C#資料庫開發專案,基本窗體程式做好之後,發現介面較為醜陋,然而,自己又不善於美工,所以想到了求助於第三方幫忙。網上有較多的是利用IrisSkin2

SpringBoot | 第二十一章:非同步開發非同步呼叫

前言 上一章節,我們知道了如何進行非同步請求的處理。除了非同步請求,一般上我們用的比較多的應該是非同步呼叫。通常在開發過程中,會遇到一個方法是和實際業務無關的,沒有緊密性的。比如記錄日誌資訊等業務。這個時候正常就是啟一個新執行緒去做一些業務處理,讓主執行緒非同步的執行其他業

React Nativejs呼叫Android原生使用Callback傳遞結果給js

1 問題 上面的文章只是呼叫安卓原生顯示Toast,但是我們一般會需要呼叫安卓的程式碼然後去拿回結果給js,但是我們知道在android層js呼叫的這個函式返回值必須的void,所以我們需要用到Callback,Callback一般用於同步,也就是說直接呼叫

Dubbo原始碼解析provider呼叫

閱讀須知 dubbo版本:2.6.0 spring版本:4.3.8 文章中使用/* */註釋的方法會做深入分析 正文 在之前的原始碼分析文章中,我們看到了dubbo用netty作為底層的網路通訊框架,熟悉netty的同學應該知道,使用netty時我們會使用它

SpringCloud遠端呼叫Feign

一.Feign 在上篇文章中,我們使用了Ribbon的負載均衡功能,大大簡化了遠端呼叫時的程式碼: String baseUrl = "http://user-service/user/"; User user = this.restTemplate.getForObject(bas

11.“撿現成”函式呼叫

1.函式是一種基本規律的抽象,可重用。例如說圓面積、正方形邊長,橢圓面積等。這些被發現的公式或定理或規律被固化下來,我們在遇到的時候可以直接套用這些定義好的函式。 2.python內建了很多的函式,這些函式為我們省去了大量的工作 3.我們可以“撿現成”直接呼叫定義

hbaseRPC呼叫流程簡介

首先分析hbase中對於master協議的呼叫: 在ConnectionImplementation的方法getKeepAliveMasterService被呼叫時,會通過MasterServiceStubMaker.makeStub()方法構建成員變數masterServiceState.stub。 在M