首页 > 系统相关 >Visual Studio 2022 C++ 生成dll或so文件在windows或linux下用C#调用

Visual Studio 2022 C++ 生成dll或so文件在windows或linux下用C#调用

时间:2024-12-03 16:37:41浏览次数:5  
标签:windows 下用 ++ C++ dll int so linux 生成

背景
开发中我们基本使用windows系统比较快捷,但是部署的时候我们又希望使用linux比较便宜,硬件产商还仅提供了c++ sdk!因此我们做二次开发时需要Visual Studio 2022在windows下 C++ 生成dll或linux下生成so库文件供C#调用。

方案
需要确认一件事,目前c++这门语言不是跨平台的

第一个问题【C++生成dll在windows下使用C#调用】解决方案:
1、使用vs2022创建一个c++ window空项目,命名为DllForWindows

 

 

2、右键单击项目名称,选择属性,并在属性中修改输出类型为动态链接库dll

 

3、为我们的源文件目录添加一个main.cpp,内容如下:

extern "C" {
    __declspec(dllexport) int add(int x, int y) { return x + y; }
    __declspec(dllexport) int sub(int x, int y) { return x - y; }
    __declspec(dllexport) int mul(int x, int y) { return x * y; }
    __declspec(dllexport) int div(int x, int y) { return x / y; }
}

设置解决方案,配置平台生成

 

4、重新生成解决方案,就可以在Debug目录下找到我们的dll了

 

 

5、新建一个C# DotNet6 控制台空项目,命名为TestDllForWindows

 

 

 

6、把Program.cs代码修改为如下,然后重新生成一下解决方案,我们会生成bin目录

using System.Runtime.InteropServices;

namespace TestDllForWindows
{
    internal class Program
    {
        [DllImport("DllForWindows.dll")]
        public static extern int add(int x, int y);

        [DllImport("DllForWindows.dll")]
        public static extern int sub(int x, int y);

        [DllImport("DllForWindows.dll")]
        public static extern int mul(int x, int y);

        [DllImport("DllForWindows.dll")]
        public static extern int div(int x, int y);
        //原文链接:https://blog.csdn.net/qq_36694133/article/details/135863027

        static void Main(string[] args)
        {
            Console.WriteLine("C# 调用C++ 生成的dll动态库!");
            int x = 10, y = 5;
            Console.WriteLine(add(x, y));
            Console.WriteLine(sub(x, y));
            Console.WriteLine(mul(x, y));
            Console.WriteLine(div(x, y));
            Console.Read();
        }
    }
}

 

7、拷贝一份我们C++生成的dll到 bin/Debug/net6.0目录,或者把DllForWindows.dll拷贝到TestDllForWindows项目中,并设置DllForWindows.dll属性 复制到输出目录--始终复制  生成操作----内容

 

 

8、运行我们的程序,可以看到结果如下

 

 

第二个问题【C++生成so在linux下使用C#调用】解决方案:

1、 使用vs2022创建一个c++ linux空项目,命名为SoForLinux

 

 2、 新建main.cpp,内容如下【与生成windows动态链接库不同,这里不需要__declspec(dllexport)修饰】

extern "C" {
    int add(int x, int y) { return x + y; }
    int sub(int x, int y) { return x - y; }
    int mul(int x, int y) { return x * y; }
    int div(int x, int y) { return x / y; }
}

3、 Linux 端准备工作

查看系统:uname -a或者uname -m

如果输出是 x86_64,那么您的系统是64位的。如果输出是 i686 或 i386,那么您的系统是32位的。

 

    • 在虚拟机中的Linux系统内查看IP地址,linux输入 ip addr|grep inet 回车

       

    • 在VS2022 中选择“工具——选项”
    • 选到“跨平台”
    • 添加远程连接
    • 主机名是IP地址
    • 端口不变
    • 用户名和密码是Linux系统对应的

       

    • 完成后点击 连接
    • 顶部可以看到连接成功,也可以选择对应的连接,选择 右边的验证,测试连接情况。

注意在使用Linux编译时可能会用到g++编译,需要安装g++编译器,还有就是远程连接可能由于防火墙问题vs2022无法连接

问题解决如下:

1、Linux系统中要先安装g++ ,这个g++是linux编译so库的工具,否则会提示 :  “g++:command not found”            

Linux安装g++:

           bash: line 1: g++: command not found

           报错解释:
                   这个错误表明在Bash环境下尝试执行g++命令时,系统找不到g++这个程序。g++是GNU项目的一部分,是一个编译C++源代码的交叉编译器。
           解决方法:
 安装g++:
如果你使用的是基于Debian的系统(如Ubuntu),可以通过以下命令安装: 
sudo apt-get update
sudo apt-get install g++ 
如果你使用的是基于Red Hat的系统(如Fedora或CentOS),可以通过以下命令安装: sudo yum update sudo yum install gcc-c++
如果你使用的是macOS,可以通过Homebrew安装: brew install gcc
如果已经安装了g++但仍然出现这个错误,可能是因为g++不在环境变量PATH中。可以通过以下命令查找g++的安装位置,并将其添加到PATH中: export PATH=$PATH:/path/to/g++ 替换/path/to/g++为g++实际的安装路径。 确认安装后的g++版本与你的代码需求是否兼容。如果需要特定版本的g++,可能需要进一步安装或更新。 如果你正在使用的是容器(如Docker)或者虚拟环境,确保在该环境中g++已经被正确安装。

2、远程连接可能由于防火墙问题vs2022无法连接     

关闭防火墙
在Ubuntu上启用并设置OpenSSH服务器,你需要执行以下步骤:

安装OpenSSH服务器软件包:
sudo apt update
sudo apt install openssh-server
服务安装后将自动启动。你可以通过运行以下命令来检查SSH服务的状态: sudo systemctl status ssh
如果SSH服务没有启动,你可以使用以下命令启动它: sudo systemctl start ssh
为了确保SSH服务在系统启动时自动启动,可以使用以下命令: sudo systemctl enable ssh
(可选)如果需要修改SSH配置,编辑 /etc/ssh/sshd_config 文件,然后重启服务: sudo systemctl restart ssh
确保Ubuntu防火墙允许SSH连接。默认情况下,OpenSSH服务器会监听端口22: sudo ufw allow ssh 现在,你应该能够从远程客户端使用SSH来连接Ubuntu系统了。使用以下命令: ssh [username]@[host-ip-address] 其中 [username] 是你的Ubuntu系统上的用户名,[host-ip-address] 是Ubuntu系统的IP地址。

 

4、右键单击项目名称,进入属性页,修改生成so文件

 

 5、重新生成解决方案,可以在Debug文件夹下看到生成了lib前缀的so文件

 查看Linux系统中,如下:

 注意:上述在vs2022在linux中使用g++编译so库时,需要注意防火墙开放指定端口(默认22,也可以开放其他端口),需要提前在linux中安装g++编译so的环境。

 

5、新建一个C# DotNet6 控制台项目,名称为TestSoForLinux

 

6、把Program.cs文件内容修改为如下

 

using System.Runtime.InteropServices;
 
namespace TestDllForWindows
{
    internal class Program
    {
        [DllImport("libSoForLinux.so")]
        static extern int add(int x, int y);
        [DllImport("libSoForLinux.so")]
        static extern int sub(int x, int y);
        [DllImport("libSoForLinux.so")]
        static extern int mul(int x, int y);
        [DllImport("libSoForLinux.so")]
        static extern int div(int x, int y);
 
        static void Main(string[] args)
        {
            int x = 10, y = 5;
            Console.WriteLine(add(x, y));
            Console.WriteLine(sub(x, y));
            Console.WriteLine(mul(x, y));
            Console.WriteLine(div(x, y));
        }
    }
}

7、编译TestSoForLinux以后,右键单击项目名称,选择【发布】

 

 

 

 

8、部署模式改为【独立:这样linux系统不需要安装dotnet运行环境,我们打包的时候就带了进去,占用磁盘会稍大一点但是省心】,目标运行时为linux-x64【本文的系统是的ubuntu x64的运行环境,其他的根据实际视情况而定】,发布选项里勾选生成单个文件【相当于vs尽可能帮我们把应用和依赖包搞成一个文件】 

 9、保存发布配置,并点击发布,发布完毕后,我们点击打开文件夹 

 10、把生成的文件TestSoForLinux和C++生成的libSoForLinux.so都拷到我们的linux系统同一文件夹下

 

11、使用终端打开此目录,输入如下命令后回车【注意有个英文小数点,linux下好像需要指定目录位置】,运行结果如下:

./TestSoForLinux 

 

注意:在Linux中/home/linjie/Desktop/linux-x64下运行 ./TestSoForLinux 时可能会遇到权限问题,

提示 Permission denied,

解决:

sudo chmod 777 /home/linjie/Desktop/linux-x64

chmod 777 /home/linjie/Desktop/linux-x64/TestSoForLinux

hmod 777 /home/linjie/Desktop/linux-x64/libSoForLinux.so

在输入

./TestSoForLinux

 

以上就是Visual Studio 2022 C++ 生成dll或so文件,在windows下用C#调用dll动态库以及在linux下用C#调用so库的全部过程,在上述过程中需要注意几点

1、在windows下用C#调用dll动态库时,C++项目DllForWindows生成动态库时,需要设置DllForWindows位Win32,解决方案中设置X86,TestDllForWindows设置X86

2、vs2022中c++项目SoForLinux生成so库,在linux下用C#调用so库时,linux环境下需要先安装g++,在开放防火墙指定端口,默认22,也可以开放其他端口,因为vs2022编译C++的so库时是远程到Linux环境使用g++来编译so库的,windows环境下没法编译,只有在linux才可以,所以为了方便直接配置远程linux环境主机来使用g++编译so库,所以需要先安装g++,在开放防火墙指定端口,这样在vs2022中c++项目SoForLinux生成so库时可以设置SoForLinux 属性 配置属性  常规 远程生成计算机 中配置linux主机。同时需要设置c++项目SoForLinux 为 X64位,而项目TestSoForLinux为 X64位或者Any CPU都可以,发布时注意根据不同的部署环境选择对应的操作系统,例如本文时Linux Ubuntu X64系统,那么发布时就需要选择linux-64 为目标运行时,部署模式 一半选择 独立,这样发布时会把环境都打包进去,在linu环境下运行时,就不需要在额外安装运行时了。

 

参考链接:https://blog.csdn.net/qq_36694133/article/details/135863027

参考链接:https://blog.csdn.net/qq_42067550/article/details/126542804?spm=1001.2101.3001.6650.17&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-17-126542804-blog-129674528.235%5Ev43%5Epc_blog_bottom_relevance_base1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-17-126542804-blog-129674528.235%5Ev43%5Epc_blog_bottom_relevance_base1&utm_relevant_index=24

参考链接:https://blog.csdn.net/wq57885/article/details/90553021/

标签:windows,下用,++,C++,dll,int,so,linux,生成
From: https://www.cnblogs.com/1175429393wljblog/p/18584362

相关文章

  • C++业务流程需要经常变更,想用Python来做流程脚本,和C++互相调用,有什么好的案例吗?
    在现代软件开发中,将性能敏感的部分用C++实现,动态变化的业务逻辑用Python编写是一种常见的做法。这种方法结合了C++的高性能和Python的灵活性,适合需要频繁变更逻辑的场景,比如业务流程、规则引擎、数据处理等。以下是一些实现C++和Python互相调用的常见方式和实际案......
  • Linux C++ 服务器端这条线怎么走?一年半能做出什么?
    选择LinuxC++服务器方向是一个非常好的发展路径,这条方向需要扎实的基础知识和实践能力,同时有着很大的发展空间。以下是一个完整的学习路线和一年半的规划,帮助你在毕业前掌握核心技能并积累项目经验。一、LinuxC++服务器方向的核心知识体系LinuxC++服务器端开发的核心......
  • c++ 环形队列(RingBuffer)
    环形缓冲区(CircularBuffer)与环形队列类似,是一种数据结构,支持在固定容量下的高效读写操作。相比队列,环形缓冲区通常允许覆盖旧数据,这在某些场景(如实时数据流、日志处理)中非常有用。实现步骤核心变量:缓冲区数组buffer[]:存储数据。读指针head:指向下一个读取的位置。写指......
  • 再谈Windows消息循环
    一、什么是Windows消息循环概念介绍在Windows操作系统中,消息循环是应用程序处理消息的核心机制。消息是Windows应用程序与操作系统以及应用程序内部不同组件之间通信的基本单元。这些消息可以是由用户操作产生的,如鼠标点击、键盘按键;也可以是系统内部产生的,如窗口大小改变......
  • WPF中嵌入第三方窗体-WindowsFormsHost使用
    嵌入第三方窗体到Windows窗体或控件中,通过调用API方法很容易实现,但是在WPF存在一些问题,这里对解决这些问题的方法做一点笔记:首先说一下要做嵌入第三方窗体要用到的API方法[DllImport("user32.dll",SetlastError=true)]privatestaticexternIntPtrSetParent(IntPtrhWndC......
  • windows下配置hadoop3.1.4环境
    文章目录说明目前情况检查Java环境配置Hadoop环境下载解压hadoop3.1.4下载插件设置环境变量报错修改Hadoop配置文件修改core-site.xml文件修改hdfs-site.xml文件修改yarn-site.xml文件修改mapred-site.xml文件修改hadoop-env.sh文件修改hadoop-env.cmd文件格式化启动集......
  • 在Windows PE(Preinstallation Environment,预安装环境)中集成PowerShell 7,可以为系统管
    在WindowsPE(PreinstallationEnvironment,预安装环境)中集成PowerShell7,可以为系统管理员提供更强大的命令行工具和自动化脚本支持。WindowsPE本身是一个轻量级的操作系统,通常用于系统部署、恢复、维修和故障排除等任务,但它默认只集成了基本的命令行工具和脚本环境(如CMD和批处理......
  • 在 Windows 11 中,WMIC(Windows Management Instrumentation Command-line)工具已被废弃,
    在Windows11中,WMIC(WindowsManagementInstrumentationCommand-line)工具已被废弃,微软推荐使用PowerShell中的Get-WmiObject和Get-CimInstance等cmdlet来替代其功能。不过,WMIC被停用可能会对一些管理和自动化任务造成影响,尤其是在一些自动化脚本或企业环境中,管理员习......
  • 蓝桥杯c++算法秒杀【7】之数据结构(修改数组、翻转括号序列、双向排序:::非常典型的必刷例
    别忘了请点个赞+收藏+关注支持一下博主喵!!!! ! !  关注博主,更多蓝桥杯nice题目静待更新:)  数据结构一、修改数组【问题描述】        给定一个长度为N的数组A=[A1,A2,...,AN],数组中有可能有重复出现的整数。        现在小明要按以下方法将其......
  • 秒开超大文件夹:如何禁止 Windows 自动识别文件夹类型
    Windows的「自动文件类型发现」功能会分析文件夹内容,以便应用最合适的视图模板。但对于包含大量文件和文件类型复杂的超大文件夹,则会导致「文件资源管理器」的打开速度变慢。本文将教你如何关闭这一功能,以加快文件夹的加载速度。什么是文件夹类型在Windows系统中,有「常规项......