zoukankan      html  css  js  c++  java
  • 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,vs里新建一个*.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
    ",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("
    
    ---- 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("
    
    ---- 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("
    
    ---- 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("
    
    ---- setCallBackFun")
    	fmt.Println(setCallBackFun.Addr())
     
    	setCallBackFun.Call((uintptr)(unsafe.Pointer(C.CallBackFun)))
     
    	handle.Release() // 释放dll 句柄
     
    }
    

      

  • 相关阅读:
    小程序 视频
    b161: NOIP2007 4.Hanoi双塔问题
    命名规则、.gitignore、freopen()
    c++学习记录(九)
    c++学习笔记(八)
    2020面向对象程序设计寒假作业2
    c++学习记录(七)
    c++学习记录(六)
    c+学习记录(五)
    c++学习记录(四)
  • 原文地址:https://www.cnblogs.com/adjk/p/9469419.html
Copyright © 2011-2022 走看看