如何在 C++ 中正确包含和 link 专有共享 object 库
How to correctly include and link a proprietary shared object library in C++
我有一个 linux c++ sdk,我需要将其作为依赖项集成到更大的 .NET 6.0 项目中。
此 sdk 仅 有条件包含在 linux 版本的软件中,我已经拥有 windows 版本 运行 否问题。
此 skd 仅在非常嵌套的命名空间中公开 classes,据我所知,[DllImport]
不支持 class 方法。
我已经知道如何创建包装器和 expose functions with extern "C"
并将 sdk 实例作为指向 .NET Core 应用程序的指针传递 运行 在 linux 系统下没问题
我的问题是我确实不知道如何将现有的 .so
文件成功地 compile/include/link 到 .dll 或 .so 中,这样我就可以 [DllImport]
sdk已经发给我了,结构如下(以name-of-lib作为占位符名称,不知道能不能暴露真实的公司名,以防万一) :
run/
|- x86/
| +- {same files as x64 but i don't target x86 arcs so it's useless}
+- x64/
|- install.sh {see #1}
|- libNameModuleA.so.1.2.3
|- libNameModuleB.so.3.2.1
|- libNameApi.so.7.8.9
+- {etc. etc.}
lib/
|- lib-name-api/
| |- doc/
| | +- somehtmlautogenerateddocs.html
| |- include/
| | +- NameApi.h
| +- source/ {optionally for the top level apis}
| +- {varius header .h files}
|- name-of-lib-module-A/
| +- {same as previus, repeat for every .so file}
+- {etc. etc.}
{#1} 脚本,craetes 链接为 libName.so => libName.so.1 => libName.so.1.2 => etc
所有这些库 header 文件相互引用,就像它们在同一个文件夹中一样,使用 #include "subLibraryModule.h"
即使该文件实际上位于 ../../subLibrary/include/subLibraryModule.h
中。
此外,在skd中只有headers。
现在,能够包含 top-level 的 cmake、make、g++、gcc 命令、配置或过程是什么(或者,我真的不知道什么是最好的工具) header 引用了编译中的所有其他内容而编译器没有 file not found
错误?
假设我需要编译一个文件 wrapper.cpp
,该文件仅包含顶层 header 并且仅包含 extern "C"
函数
我试过用 vscode 做这件事,intellisense 实际上正确地解析了 headers,但是当我尝试编译它时,一切都突然变成了 file-not-founds
我是不是漏掉了什么?我错过了更多信息或文件吗?
提前致谢。
所以我想通了。
生成文件
这里唯一的问题是我不知道如何使用 glob 模式自动包含内容(比如 -Ilib/*/include
),但无论如何。
CC := g++
SRC := wrapper.cpp
OBJ := wrapper.o
OUT := libWrapper.so
INCs := -Ilib/lib-name-api/include -Ilib/name-lib-module-A/include {etc. etc.}
LIB := -L/usr/local/lib/installedLibNameSos/ -lNameModuleA -lNameModuleB {etc. etc.}
all: $(OUT)
$(OUT): $(OBJ)
$(CC) $(OBJ) -shared -o $(OUT) $(LIB)
$(OBJ): $(SRC)
$(CC) -c $(SRC) -o $(OBJ) $(INCs) $(LIB)
wrapper.cpp
#include <stdio.h>
#include "NameApi.h"
// varius using namespace and other import stuff
extern "C" int test (){
return 42;
}
extern "C" string somethingReturningAString (){
// calls and stuff to the native library
return "Hi mom"
}
显然需要将 .so 复制到可执行文件所在的位置
csharpClass.cs
using System;
using System.Runtime.InteropServices;
// extension not needed.
// the library will be loaded along with the required .so's
// that have been linked from /usr/local/lib/installedLibNameSos/
[DllImport("libWrapper")]
extern static int test ();
[DllImport("libWrapper")]
extern static string somethingReturningAString ();
Console.WriteLine(test());
// 42
Console.WriteLine(somethingReturningAString());
// Hi mom
资源:
- Link .so file to .cpp file via g++ compiling
- Call C++ library in C#
- https://en.wikipedia.org/wiki/Platform_Invocation_Services(p/Invoke 个例子)
- https://docs.microsoft.com/en-us/dotnet/standard/native-interop/cross-platform
(注意:这个过程完美无缺。但我一直在使用一个由一只痉挛猴子编写和记录的库。所以是的,我真的学习了 g++ 的基础知识,无缘无故地产生了严重的抑郁症。大声笑)
我有一个 linux c++ sdk,我需要将其作为依赖项集成到更大的 .NET 6.0 项目中。
此 sdk 仅 有条件包含在 linux 版本的软件中,我已经拥有 windows 版本 运行 否问题。
此 skd 仅在非常嵌套的命名空间中公开 classes,据我所知,[DllImport]
不支持 class 方法。
我已经知道如何创建包装器和 expose functions with extern "C"
并将 sdk 实例作为指向 .NET Core 应用程序的指针传递 运行 在 linux 系统下没问题
我的问题是我确实不知道如何将现有的 .so
文件成功地 compile/include/link 到 .dll 或 .so 中,这样我就可以 [DllImport]
sdk已经发给我了,结构如下(以name-of-lib作为占位符名称,不知道能不能暴露真实的公司名,以防万一) :
run/
|- x86/
| +- {same files as x64 but i don't target x86 arcs so it's useless}
+- x64/
|- install.sh {see #1}
|- libNameModuleA.so.1.2.3
|- libNameModuleB.so.3.2.1
|- libNameApi.so.7.8.9
+- {etc. etc.}
lib/
|- lib-name-api/
| |- doc/
| | +- somehtmlautogenerateddocs.html
| |- include/
| | +- NameApi.h
| +- source/ {optionally for the top level apis}
| +- {varius header .h files}
|- name-of-lib-module-A/
| +- {same as previus, repeat for every .so file}
+- {etc. etc.}
{#1} 脚本,craetes 链接为 libName.so => libName.so.1 => libName.so.1.2 => etc
所有这些库 header 文件相互引用,就像它们在同一个文件夹中一样,使用 #include "subLibraryModule.h"
即使该文件实际上位于 ../../subLibrary/include/subLibraryModule.h
中。
此外,在skd中只有headers。
现在,能够包含 top-level 的 cmake、make、g++、gcc 命令、配置或过程是什么(或者,我真的不知道什么是最好的工具) header 引用了编译中的所有其他内容而编译器没有 file not found
错误?
假设我需要编译一个文件 wrapper.cpp
,该文件仅包含顶层 header 并且仅包含 extern "C"
函数
我试过用 vscode 做这件事,intellisense 实际上正确地解析了 headers,但是当我尝试编译它时,一切都突然变成了 file-not-founds
我是不是漏掉了什么?我错过了更多信息或文件吗?
提前致谢。
所以我想通了。
生成文件
这里唯一的问题是我不知道如何使用 glob 模式自动包含内容(比如 -Ilib/*/include
),但无论如何。
CC := g++
SRC := wrapper.cpp
OBJ := wrapper.o
OUT := libWrapper.so
INCs := -Ilib/lib-name-api/include -Ilib/name-lib-module-A/include {etc. etc.}
LIB := -L/usr/local/lib/installedLibNameSos/ -lNameModuleA -lNameModuleB {etc. etc.}
all: $(OUT)
$(OUT): $(OBJ)
$(CC) $(OBJ) -shared -o $(OUT) $(LIB)
$(OBJ): $(SRC)
$(CC) -c $(SRC) -o $(OBJ) $(INCs) $(LIB)
wrapper.cpp
#include <stdio.h>
#include "NameApi.h"
// varius using namespace and other import stuff
extern "C" int test (){
return 42;
}
extern "C" string somethingReturningAString (){
// calls and stuff to the native library
return "Hi mom"
}
显然需要将 .so 复制到可执行文件所在的位置
csharpClass.cs
using System;
using System.Runtime.InteropServices;
// extension not needed.
// the library will be loaded along with the required .so's
// that have been linked from /usr/local/lib/installedLibNameSos/
[DllImport("libWrapper")]
extern static int test ();
[DllImport("libWrapper")]
extern static string somethingReturningAString ();
Console.WriteLine(test());
// 42
Console.WriteLine(somethingReturningAString());
// Hi mom
资源:
- Link .so file to .cpp file via g++ compiling
- Call C++ library in C#
- https://en.wikipedia.org/wiki/Platform_Invocation_Services(p/Invoke 个例子)
- https://docs.microsoft.com/en-us/dotnet/standard/native-interop/cross-platform
(注意:这个过程完美无缺。但我一直在使用一个由一只痉挛猴子编写和记录的库。所以是的,我真的学习了 g++ 的基础知识,无缘无故地产生了严重的抑郁症。大声笑)