在 Linux 下,.NET Core 或 .NET 5+ 支持通过 P/Invoke(Platform Invoke)技术调用本地库(通常是 `.so` 文件)。这种方法允许您在托管的 C# 代码中调用非托管的 C/C++ 代码。

以下是一个简单的示例,展示如何在 Linux 下的 C# 代码中调用一个简单的 `.so` 库文件中的函数。

### 步骤 1:创建一个简单的 C 库

首先,创建一个简单的 C 库,用于演示调用过程。假设我们要创建一个名为 `example.so` 的库文件,其中包含一个打印字符串的函数。

#### 创建 C 头文件 `example.h`

```c
#ifndef EXAMPLE_H
#define EXAMPLE_H

// 定义一个 C 函数
extern void print_message(const char *message);

#endif
```

#### 创建 C 源文件 `example.c`

```c
#include <stdio.h>
#include "example.h"

void print_message(const char *message) {
printf("%s\n", message);
}
```

#### 编译 C 库

使用 GCC 编译 C 源文件,生成共享对象文件 `.so`。

```bash
gcc -shared -o example.so example.c -fPIC
```

### 步骤 2:创建 C# 项目并调用 `.so` 库

接下来,创建一个 C# 控制台应用程序,并在其中调用上面创建的 `.so` 库。

#### 创建 C# 项目

打开 Visual Studio Code 或其他编辑器,并创建一个新的 C# 控制台应用程序。

```bash
mkdir ExampleApp
cd ExampleApp
dotnet new console
```

#### 引入 `.so` 库

编辑 `Program.cs` 文件,添加必要的 P/Invoke 代码。

```csharp
using System;
using System.Runtime.InteropServices;

namespace ExampleApp
{
class Program
{
// 指定库文件的名称
private const string LibName = "example";

// 声明 P/Invoke 函数
[DllImport(LibName, EntryPoint = "print_message", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void PrintMessage(string message);

static void Main(string[] args)
{
// 调用 C 库中的函数
PrintMessage("Hello from C#!");

Console.WriteLine("Called C function from C#.");
}
}
}
```

### 步骤 3:设置环境变量

确保 `.so` 文件所在目录包含在 `LD_LIBRARY_PATH` 环境变量中,以便程序能够找到库文件。

```bash
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/your/library/directory
```

### 步骤 4:编译并运行 C# 应用程序

编译并运行 C# 应用程序:

```bash
dotnet build
dotnet run
```

如果一切正常,您应该会在控制台看到输出的信息。

### 完整示例

下面是完整的示例代码,包括 C 头文件、源文件和 C# 代码。

#### `example.h`

```c
#ifndef EXAMPLE_H
#define EXAMPLE_H

// 定义一个 C 函数
extern void print_message(const char *message);

#endif
```

#### `example.c`

```c
#include <stdio.h>
#include "example.h"

void print_message(const char *message) {
printf("%s\n", message);
}
```

#### 编译 C 库

```bash
gcc -shared -o example.so example.c -fPIC
```

#### `Program.cs`

```csharp
using System;
using System.Runtime.InteropServices;

namespace ExampleApp
{
class Program
{
// 指定库文件的名称
private const string LibName = "example";

// 声明 P/Invoke 函数
[DllImport(LibName, EntryPoint = "print_message", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void PrintMessage(string message);

static void Main(string[] args)
{
// 调用 C 库中的函数
PrintMessage("Hello from C#!");

Console.WriteLine("Called C function from C#.");
}
}
}
```

### 总结

以上示例展示了如何在 Linux 下的 C# 代码中通过 P/Invoke 调用一个简单的 `.so` 库文件。通过这种方式,您可以轻松地将本地 C/C++ 代码集成到您的 .NET Core 或 .NET 5+ 应用程序中。如果您需要调用更复杂的库,可以根据需要扩展上述示例。

c#调用so的更多相关文章

  1. 黑马毕向东Java基础知识总结

    Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记    侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...

  2. 《果壳中的C# C# 5.0 权威指南》 - 学习笔记

    <果壳中的C# C# 5.0 权威指南> ========== ========== ==========[作者] (美) Joseph Albahari (美) Ben Albahari ...

  3. JS调用Android、Ios原生控件

    在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...

  4. 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付

    前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...

  5. 操作系统篇-调用门与特权级(CPL、DPL和RPL)

    || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在前两篇文章(<操作系统篇-浅谈实模式与保护模式>和<操作系统篇-分段机制与GDT|LDT>)中,我们提到 ...

  6. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  7. django server之间通过remote user 相互调用

    首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...

  8. 调用AJAX做登陆和注册

    先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...

  9. nodejs进阶(2)—函数模块调用

    函数调用 1. 文件内普通函数调用 创建一个js文件命名为2_callFunction.js,其中定义一个函数fun1,向返回对象输出了一段字符串“你好,我是fun1”. //------------ ...

  10. 【初学python】使用python调用monkey测试

    目前公司主要开发安卓平台的APP,平时测试经常需要使用monkey测试,所以尝试了下用python调用monkey,代码如下: import os apk = {'j': 'com.***.test1 ...

随机推荐

  1. AtCoder Beginner Contest 408 E-F 题解

    E. Minimum OR Path 题意 给你一个 \(N\) 个点 \(M\) 条边的无自环的无向图,第 \(i\) 条边连接 \(u_i\) 和 \(v_i\),权值为 \(w_i\). 在所有 ...

  2. Cocos3内置Effect(着色器)介绍

    创建材质后Effect有很多下拉选项,介绍一下: 在 Cocos Creator 中,材质(Material) 是用于定义物体表面渲染效果的资源,而 Effect(效果文件) 是材质的核心,它定义了如 ...

  3. 使用 SpringBoot 集成 WebService [不需要身份验证]

    一.使用 JDK 自带的工具生成实体类 # 格式 wsimport -s 保存路径 -p 包路径 -encoding utf-8 wsdl文件地址 # 实例 wsimport -s d:\wsdl - ...

  4. 一文搞定AB测试

    import numpy as npimport scipy.stats as statsimport pandas as pd'''场景:当已知总体标准差,对总体均值进行估计,用z检验'''def ...

  5. poi 酱放过的每日一歌

    整理一下 poi 酱放过的每日一歌,大概按照时间排序,如果有喜欢的大家可以参考一下. poi 酱喜欢什么样的歌 基本上从 \(2 \times 2\) 个维度考虑:唱腔(甜度.软度)和歌词(内容.与曲 ...

  6. 645仪表以JSON格式上发方法

    1.概述 之前我们已经介绍了Modbus RTU仪表实现JSON格式上发云服务器的方法,类似的现在也可以支持645协议的仪表通过JSON格式上发服务器. 卓岚实现645仪表转JSON网关的特点有: 1 ...

  7. GPRS DTU

    GPRS DTU ZLAN8305/ZLAN8305L是上海卓岚新推出的一款高性价比的串口232/485转GPRS DTU.这款的核心亮点是支持M级别的数据暂时存储 高性价比 支持MQTT 支持全网通 ...

  8. Excel双向柱状图的绘制

    Excel双向柱状图在绘制增减比较的时候经常用到,叫法繁多,双向柱状图.上下柱状图.增减柱状图都有. 这里主要介绍一下Excel的基础绘制方法和复杂一点的双向柱状图的绘制 基础双向柱状图的绘制 首先升 ...

  9. 前端开发系列118-进阶篇之Call by sharing(值传递还是引用传递)

    JavaScript 语言中,函数调用时候参数的传递是"值传递"还是"引用传递" ? 在 JavaScript 语言中 ,函数参数传递的是「值」而非「引用」,即 ...

  10. python如何将 数组文件 存储为json文件以及对于json文件的读取

    简介 最近项目中要用到PCA计算,PCA从文件中读取数据,然后再写入数据 code #encoding = utf-8 import numpy as np import json from skle ...