go语言 c# 混合编程 pdf,C# 结合 Golang 开发

1. 实现方式与语法形式

基本方式:将 Go 程序编译成 DLL 供 C# 调用。

1.1 Go代码

注意:代码中 export 的注释是定义的入口描述不能省略

package main

import "C"

import "fmt"

func main() {

fmt.Println(Test())

}

var _count = 0

//Test :

//export Test

func Test() int {

_count++

return _count

}

在 LiteIDE 中将编译配置的 BUILDARGS 自定义值为 --buildmode=c-shared -o Test.dll,从而形成以下编译语句。

go build --buildmode=c-shared -o Test.dll

1.2 C# 代码

[DllImport("Test.dll", EntryPoint = "Test")]

extern static int Test();

2. Windows 下编译依赖的环境

生成 DLL 依赖于 gcc,没有 gcc 环境时,会报以下错误:

"gcc": executable file not found in %PATH%

3. 操作系统 64 位与 32 的编译

在 LiteIDE 中,可以通过配置 win32.env 和 win64.env 来指定不同的 gcc 环境路径达到生成指定系统的 DLL 文件。

4. c# 中操作系统 64 位与 32 的适配

在 c# 中判断操作系统是否 64 位,可以使用以下语句。

bool is64 = Environment.Is64BitOperatingSystem;

为了在不同的操作系统下,加载不同的 DLL,采取以下步骤来进行组织。

(1)将 32 位的版本命名为 Test32.dll,将 64 位的版本命名为 Test64.dll

(2)定义 ITest 接口,将 DLL 将要调用的方法定义为接口方法

(3)分别为ITest接口实现 Test32 与 Test64 类,在类中加载相应的 DLL

(4)通过判断操作系统类型,实例化一个 ITest 的具体实现类实例来使用

具体接口与类实现代码如下:

public interface ITest

{

int Test();

}

public class Test32 : ITest

{

class TestDLL

{

const string DLL_NAME = "Test32.dll";

[DllImport(DLL_NAME, EntryPoint = "Test")]

public extern static int Test();

}

public int Test()

{

return TestDLL.Test();

}

}

public class Test64 : ITest

{

class TestDLL

{

const string DLL_NAME = "Test64.dll";

[DllImport(DLL_NAME, EntryPoint = "Test")]

public extern static int Test();

}

public int Test()

{

return TestDLL.Test();

}

}

实例化与调用:

ITest test = Environment.Is64BitOperatingSystem ? (ITest)new Test64() : (ITest)new Test32();

int result = test.Test();

还有一种方式:

[DllImport("kernel32")]

private static extern IntPtr LoadLibraryA([MarshalAs(UnmanagedType.LPStr)] string fileName);

-- DllImport 会先在加载的里边找名称,可以预先加载。

LoadLibraryA((Environment.Is64BitOperatingSystem ? "x64" : "x86") + "/Test.dll");

补充一下 LoadLibrary 的查找路径说明

LoadLibrary的查找路径,可以参见MSDN上的文章:Dynamic-Link Library Search Order。

默认情况如下:

The directory from which the application loaded. (应用程序所在的目录)

The system directory. Use the GetSystemDirectory function to get the path of this directory. (system32目录)

The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. (System目录)

The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. (Windows目录)

The current directory. (当前目录,执行命令的发起目录)

The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. (PATH路径)

5. 其它一些问题

5.1 字符串转换

传入字符串,C#: byte[] -> GO: *C.char

接收字符串,GO: string -> C#: GoString struct

GO 定义示例

//Hello :

//export Hello

func Hello(name *C.char) string {

return fmt.Sprintf("hello %s", C.GoString(name))

}

C# GoString struct 定义

public struct GoString

{

public IntPtr p;

public int n;

public GoString(IntPtr n1, int n2)

{

p = n1; n = n2;

}

}

C# DllImport 声明

[DllImport(DLL_NAME, EntryPoint = "Hello", CallingConvention = CallingConvention.Cdecl)]

public extern static GoString Hello(byte[] name);

C# GoString struct 转 String

public string GoStringToCSharpString(GoString goString)

{

byte[] bytes = new byte[goString.n];

for (int i = 0; i < goString.n; i++)

{

bytes[i] = Marshal.ReadByte(goString.p, i);

}

string result = Encoding.UTF8.GetString(bytes);

return result;

}

C# 调用示例

GoString goResult = test.Hello(Encoding.UTF8.GetBytes("张三"));

Debug.WriteLine(GoStringToCSharpString(goResult));

5.2 调试

CallingConvention

在声明中加入 CallingConvention = CallingConvention.Cdecl 避免未知异常。

[DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl)]

程序崩溃甚至异常提示都没有,可在加载 DLL 之前:

Environment.SetEnvironmentVariable("GODEBUG", "cgocheck=0");

6. 相关参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/571094.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 屏幕坐标色彩,Android自定义View实现颜色选取器

Android 自定义View 颜色选取器&#xff0c;可以实现水平、竖直选择颜色类似 SeekBar 的方式通过滑动选择颜色。效果图xml 属性1.indicatorColor 指示点颜色2.indicatorEnable 是否使用指示点3.orientation 方向horizontal 水平vertical 竖直使用复制 \library\src…\ColorPick…

android移除动画,android – 如何使用ObjectAnimator删除动画的慢端?

我有这个ObjectAnimator&#xff1a;cloudAnim2 ObjectAnimator.ofFloat(cloud2ImageView,"x",500,1000);cloudAnim2.setDuration(3000);cloudAnim2.setRepeatCount(ValueAnimator.INFINITE);cloudAnim2.setRepeatMode(ValueAnimator.RESTART);cloudAnim2.start();c…

linux右键菜单的截图,Linux: 给右键菜单加一个“转换图片为jpg格式”

Linux上通常都会安装imagemagick这个小巧但又异常强大的工具。这个软件提供了一系列很好用的功能。这里说一说如何使用它的convert命令转换图片为jpg格式&#xff0c;以及如何把它添加到Thunar的右键菜单。convert转换图片为jpg格式用起来超简单&#xff1a;convert -format jp…

eclipse实现Android登录功能,eclipse开发安卓登录

划线的地方怎么解决啊&#xff1f;有没有大佬知道如何修改package com.example.login;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.SharedPreferences;import android.content.SharedPreferences.Edito…

android tcp 最优窗口,Android 面试必备 - 计算机网络基本知识(TCP,UDP,Http,https)...

简介HTTP协议(超文本传输协议)和 UDP(用户数据包协议)&#xff0c;TCP 协议(传输控制协议)TCP/IP是个协议组&#xff0c;可分为四个层次&#xff1a;网络接口层、网络层、传输层和应用层。在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。在传输层中有TCP协议与UDP…

c语言10个数如何求最大值,C语言,输入10个数怎样输出10个数中最大值,最小值(大一计算机)...

可以参考下面的代码&#xff1a;#include int main(){int loop 10;int min, max, value;do{printf("输入整数:");scanf("%d", &value);if (loop10) {max min value; loop--; continue;} else {if (value > max) max value;if (value loop--;}} …

android波纹效果弹窗,Android自定义View实现波纹效果

Android自定义View实现波纹效果时间&#xff1a;2017-05-27 来源&#xff1a;移动互联网学院1、引言&#xff1a;随着Android智能手机的普及&#xff0c;Android应用得到了大力支持&#xff0c;而Android应用的市场前景也是非常的强势。在Android应用的实际开发中&#xff…

Python 构建前端 页面继承及共享 - 转

http://blog.csdn.net/youzhouliu/article/details/52181549转载于:https://www.cnblogs.com/wag-tail-118/articles/8564522.html

android service onlowmemory,Android乱弹onLowMemory()和onTrimMemory()

今天看郭哥的LitePal框架的源码,刚打开LitePalApplication里面的源码看到了这样一幕Overridepublic void onLowMemory() {super.onLowMemory();mContext getApplicationContext();}不太懂郭哥的意思.之前依稀记得有人说起onLowMemory()和onTrimMemory(),于是乎,我就去查了查源…

图像滤镜艺术---Oilpaint油画滤镜

图像滤镜艺术---Oilpaint油画滤镜 原文:图像滤镜艺术---Oilpaint油画滤镜Oilpaint油画滤镜 图像油画效果实际上是将图像边缘产生一种朦胧&#xff0c;雾化的效果&#xff0c;同时&#xff0c;将一定的边缘模糊化&#xff0c;这样图像整体上看去像素与像素之间就像雾一样随机呈现…

vs2019创建android,Visual Studio 2019编写的安卓程序,生成失败

下载实例不改动任何能够编译成功&#xff0c;稍加改动无法编译成功。布局代码&#xff1a;xmlns:android"http://schemas.android.com/apk/res/android"android:orientation"vertical"android:layout_width"fill_parent"android:layout_height&q…

android来电事件,android – 来电时没有响铃事件

我不知道问题出在哪里.监听器没有捕获到铃声事件(所以我可以决定接受还是拒绝来电).在清单中是这样的&#xff1a;在主要活动onCreate是这样的&#xff1a;IntentFilter filter new IntentFilter();filter.addAction("android.SipDemo.INCOMING_CALL");callReceiver…

转:数据库收缩

1. 数据库的相关属性 在MS中创建数据库时会为数据库分配初始的大小&#xff08;如下图&#xff1a;数据库和日志两个文件&#xff09;&#xff0c;随着数据库的使用文件会逐渐增大。数据库文件大小的增加有两种方式&#xff1a; 自动增长&#xff1a;在自动增长中可以设置每次的…

python操作excel常用的方法

读操作模块安装  pip install xlrd 写操作模块安装  pip install xlwt xlrd读操作 1、打开excel   xl xlrd.open_workbook(test.xls) 2、通过索引获取工作表   table xl.sheet()[0] #有多个sheet&#xff0c;获取第一个sheet 3、获取第一行的内容   row table.row…

懒加载与预加载

前端性能优化中图片资源的优化。 1.懒加载&#xff08;延迟加载&#xff09; 1.图片进入可视区域之后请求图片资源&#xff1b; 2.对于电商等图片较多&#xff0c;页面很长的业务场景很适用&#xff1b; 3.可以减少无效资源的加载&#xff1b; 4.并发加载的资源过多会阻塞js的加…

8.使用Exists监控ZNode的三大Change事件

一、 zookeeper是一个分布式的协调程序&#xff08;所有程序都是通过订阅它来相互感知&#xff09;1. tcp&#xff08;长链接&#xff09; watcherserver -》clientclient -》server2. Driver 中的方法 exists() 监控一个znode的 CURD 的操作。client1 client2 同时订阅 baidu…

广东 职称英语计算机,现在评职称英语和计算机都不用考了

技校网专门为您推荐的类似问题答案问题1&#xff1a;通过出版职业资格考试中级考试,评职称需要职称英语和计算机条件不跟随 已跟随 取消 确定 1、要看职称委员会的要求而定。 2、看你中级报的是什么中级&#xff1f;如是工程师&#xff0c;就要参加全国的职称英语和计算机考试&…

[SDOI2016]储能表

Description 有一个 n 行 m 列的表格&#xff0c;行从 0 到 n−1 编号&#xff0c;列从 0 到 m−1 编号。每个格子都储存着能量。最初&#xff0c;第 i 行第 j 列的格子储存着 (i xor j) 点能量。所以&#xff0c;整个表格储存的总能量是&#xff0c; 随着时间的推移&#xff0…

军用计算机ip等级是什么,加固计算机的IP防护等级是什么?

加固计算机的IP防护等级是什么&#xff1f;作者&#xff1a;鲁成伟业 | 时间&#xff1a;2021-04-28 09:00:43 | 人已围观加固计算机是各种现代化w器z备系统、j事电子信息系统以及国防科研系统中不可缺少的、到处可见的设备。小到嵌入式的微处理器&#xff0c;大到百万亿次级的…

SpringMvc渲染视图

这篇博文讨论的问题是从ModelAndView如何渲染到页面。 首先要知道每个请求处理完之后都会返回一个ModelAndView对象。 这里我分6种情况来分析&#xff0c;代表6种返回类型&#xff1a; ModelAndViewMap&#xff0c;ModelMapModelViewStringVoid我先贴出我的测试的后台代码&…