[英]Cross platform c++ integrated with c# in Linux and Windows
我在C ++中有以下代码来确定OS中的可用RAM
#if defined(_WIN32)
#include <stdio.h>
#include <windows.h>
#include "string.h"
#include "setjmp.h"
#elif defined(__linux__)
#include "stdio.h"
#include "string.h"
#include <unistd.h>
#endif
extern "C"
{
unsigned long long getAvailableSystemMemory_Windows64();
unsigned long long getAvailableSystemMemory_Linux64();
}
#if defined(_WIN32)
__declspec(dllexport) extern unsigned long long getAvailableSystemMemory_Windows64()
{
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullAvailPhys / 1024 / 1024;
}
#elif defined(__linux__)
extern unsigned long long getAvailableSystemMemory_Linux64()
{
unsigned long long ps = sysconf(_SC_PAGESIZE);
unsigned long long pn = sysconf(_SC_AVPHYS_PAGES);
unsigned long long availMem = ps * pn;
return availMem / 1024 / 1024;
}
#endif
int main()
{
#if defined(_WIN32)
printf("%d", getAvailableSystemMemory_Windows64());
#elif defined(__linux__)
printf("%d", getAvailableSystemMemory_Linux64());
#endif
printf("MB");
int a;
scanf("This is the value %d", &a);
}
和下面的代码在C#中
class Program
{
[DllImport("hello.dll", CallingConvention = CallingConvention.Cdecl)]
extern static long getAvailableSystemMemory_Windows64();
[DllImport("hello.so", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, EntryPoint = "getAvailableSystemMemory_Linux64")]
extern static long getAvailableSystemMemory_Linux64();
static void Main(string[] args)
{
long text = 0;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
text = getAvailableSystemMemory_Windows64();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
text = getAvailableSystemMemory_Linux64();
Console.WriteLine(text);
Console.WriteLine("Hello World!");
Console.ReadLine();
}
}
然后在Windows中,我使用g++ --shared -o hello.dll hello.cpp
编译c ++代码,并将dll复制到debug文件夹。 一切都好。
对于Linux,我使用g++ -o hello.so hello.cpp
在Opensuse上进行编译,然后将.so
文件复制到调试中,但是它不起作用。 我例外
Unhandled Exception: System.DllNotFoundException: Unable to load shared
library 'hello.so' or one of its dependencies. In order to help diagnose
loading problems, consider setting the LD_DEBUG environment variable:
libhello.so.so: cannot dynamically load executable
at CallCDll.Program.getAvailableSystemMemory_Linux64()
at CallCDll.Program.Main(String[] args) in
/home/CallCDll/Program.cs:line 22
我使用LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/CallCDll/bin/Debug/netcoreapp2.2
将.so
文件目录路径添加到LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/CallCDll/bin/Debug/netcoreapp2.2
但不起作用。
我该怎么办? 无论我将.so
文件复制到哪里,都找不到它。
根据[man7]:GCC(1) ( man gcc
):
-共享
产生一个共享对象,然后可以将其与其他对象链接以形成可执行文件。 并非所有系统都支持此选项。 为了获得可预测的结果,在指定此链接器选项时,还必须指定用于编译的相同选项集( -fpic , -fPIC或model子选项)。[1]
因此,您的命令不是生成共享对象或库( .so ),而是生成可执行文件(即使命名为hello.so )。 如果尝试运行它,则会看到main的输出。
要解决问题,请将您的构建命令更改为:
g++ -shared -fPIC -o hello.so hello.cpp
其他说明 :
__declspec(dllexport)
, 跨平台处理它的常用方法是通过宏。 有很多例子(我也有几个例子),这是一个例子: [SO]:Python ctypes返回一个函数指针数组(@CristiFati的回答) ( DLL00_EXPORT宏) [DllImport("libhello.so", ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.