How to call functions in. so file in Linux (Ubuntu) system
In my code,I'm trying to import funtion like:
#import "libsro.so"
int TrainNetwork(int inputSize, double& data[], int Bars, int training_bars, int BarfeatureCount);//---check
void GetTrainingProgress(double &accuracy, double &progress, double &average_loss);
bool IsTraining();
double PredictNextBar(int inputSize, double& data[], int Bars, int training_bars, int BarfeatureCount);
#import
The compilation of the expert program has been successful.
But when i run the expert,I have received the following feedback
I'm sure the libsro.so is 64-bit version:
file libsro.so
libsro.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=3a93d3f2e299a0ffed5e86d747a1b79bf016d650, not stripped
Some components of CUDA, such as NCCL, cannot run on Windows, so the. so file is an important attempt.
So, how can i use .so file in my expert?
Hi, Dominik Egert.Thank you for providing the idea. Follow your idea, I have made multiple attempts at the code of the wrapper. But i failed. For example, the following is one of the representative attempts of my code:
#include <windows.h> #include <string> #include <stdexcept> // Function pointers extern "C" { typedef int (*TrainNetworkFunc)(int, double*, int, int, int); typedef void (*GetTrainingProgressFunc)(double*, double*, double*); typedef bool (*IsTrainingFunc)(); typedef double (*PredictNextBarFunc)(int, double*, int, int, int); } TrainNetworkFunc g_TrainNetwork = nullptr; GetTrainingProgressFunc g_GetTrainingProgress = nullptr; IsTrainingFunc g_IsTraining = nullptr; PredictNextBarFunc g_PredictNextBar = nullptr; HMODULE g_hModule = nullptr; bool LoadLibraryAndFunctions() { if (g_hModule) return true; // Already loaded g_hModule = LoadLibrary("/usr/local/lib/libsro.so"); if (!g_hModule) { return false; } g_TrainNetwork = (TrainNetworkFunc)GetProcAddress(g_hModule, "TrainNetwork"); g_GetTrainingProgress = (GetTrainingProgressFunc)GetProcAddress(g_hModule, "GetTrainingProgress"); g_IsTraining = (IsTrainingFunc)GetProcAddress(g_hModule, "IsTraining"); g_PredictNextBar = (PredictNextBarFunc)GetProcAddress(g_hModule, "PredictNextBar"); return (g_TrainNetwork && g_GetTrainingProgress && g_IsTraining && g_PredictNextBar); } void UnloadLibrary() { if (g_hModule) { FreeLibrary(g_hModule); g_hModule = nullptr; g_TrainNetwork = nullptr; g_GetTrainingProgress = nullptr; g_IsTraining = nullptr; g_PredictNextBar = nullptr; } } extern "C" { __declspec(dllexport) int __stdcall TrainNetwork(int inputSize, double* data, int Bars, int training_bars, int BarfeatureCount) { if (!LoadLibraryAndFunctions()) { return -2; } return g_TrainNetwork(inputSize, data, Bars, training_bars, BarfeatureCount); } __declspec(dllexport) void __stdcall GetTrainingProgress(double* accuracy, double* progress, double* average_loss) { if (LoadLibraryAndFunctions()) { g_GetTrainingProgress(accuracy, progress, average_loss); } } __declspec(dllexport) bool __stdcall IsTraining() { if (LoadLibraryAndFunctions()) { return g_IsTraining(); } return false; } __declspec(dllexport) double __stdcall PredictNextBar(int inputSize, double* data, int Bars, int training_bars, int BarfeatureCount) { if (LoadLibraryAndFunctions()) { return g_PredictNextBar(inputSize, data, Bars, training_bars, BarfeatureCount); } return -1.0; } } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // Initialize break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: UnloadLibrary(); break; } return TRUE; } //FINISH All
I use x86_64-w64-mingw32-g++ -shared -o sro_wrapper.dll ../sro_wrapper.cpp -lkernel32 to compile it, and i got sro_wrapper.dll. I put the dll in Libraries of MQL5(in wine),but when i run the expert, the sro_wrapper.dll can't use functions in libsro.so.
I have had discussions with Claude3.5 and GPT-4o from various angles, and have also tried various solutions. In the end, it seems that the solution has been stabilized in the following code:
#include <windows.h> #include <iostream> #include <string> // 声明Wine特定的函数 extern "C" void* wine_dlopen(const char* filename, int flag); extern "C" void* wine_dlsym(void* handle, const char* symbol); extern "C" int wine_dlclose(void* handle); // 定义RTLD_NOW,因为MinGW可能没有定义它 #ifndef RTLD_NOW #define RTLD_NOW 2 #endif // 函数指针类型定义 typedef int (*TrainNetworkFunc)(int, double*, int, int, int); typedef void (*GetTrainingProgressFunc)(double*, double*, double*); typedef bool (*IsTrainingFunc)(); typedef double (*PredictNextBarFunc)(int, double*, int, int, int); // 全局函数指针 TrainNetworkFunc g_TrainNetwork = nullptr; GetTrainingProgressFunc g_GetTrainingProgress = nullptr; IsTrainingFunc g_IsTraining = nullptr; PredictNextBarFunc g_PredictNextBar = nullptr; void* g_hModule = nullptr; bool LoadLibraryAndFunctions() { if (g_hModule) return true; // 已经加载过了 const char* libPath = "/usr/local/lib/libsro.so"; g_hModule = wine_dlopen(libPath, RTLD_NOW); if (!g_hModule) { std::cerr << "Failed to load libsro.so" << std::endl; return false; } g_TrainNetwork = (TrainNetworkFunc)wine_dlsym(g_hModule, "TrainNetwork"); g_GetTrainingProgress = (GetTrainingProgressFunc)wine_dlsym(g_hModule, "GetTrainingProgress"); g_IsTraining = (IsTrainingFunc)wine_dlsym(g_hModule, "IsTraining"); g_PredictNextBar = (PredictNextBarFunc)wine_dlsym(g_hModule, "PredictNextBar"); if (!g_TrainNetwork || !g_GetTrainingProgress || !g_IsTraining || !g_PredictNextBar) { std::cerr << "Failed to load one or more functions from libsro.so" << std::endl; wine_dlclose(g_hModule); g_hModule = nullptr; return false; } return true; } // 导出函数 extern "C" { __declspec(dllexport) int __stdcall TrainNetwork(int inputSize, double* data, int Bars, int training_bars, int BarfeatureCount) { if (!LoadLibraryAndFunctions()) { return -2; } return g_TrainNetwork(inputSize, data, Bars, training_bars, BarfeatureCount); } __declspec(dllexport) void __stdcall GetTrainingProgress(double* accuracy, double* progress, double* average_loss) { if (LoadLibraryAndFunctions()) { g_GetTrainingProgress(accuracy, progress, average_loss); } } __declspec(dllexport) bool __stdcall IsTraining() { if (LoadLibraryAndFunctions()) { return g_IsTraining(); } return false; } __declspec(dllexport) double __stdcall PredictNextBar(int inputSize, double* data, int Bars, int training_bars, int BarfeatureCount) { if (!LoadLibraryAndFunctions()) { return -2.0; } return g_PredictNextBar(inputSize, data, Bars, training_bars, BarfeatureCount); } } // 在DLL卸载时释放资源 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_DETACH: if (g_hModule) { wine_dlclose(g_hModule); g_hModule = nullptr; } break; } return TRUE; } //FINISH All
But I can't compile it. Because wine_dlopen,wine_dlsym are internal functions of wine, and I haven't found a way to call it yet.
I've been crazy about this problem these past few days.
Can you give me some tips, articles, or examples?
In my code,I'm trying to import funtion like:
#import "libsro.so"
int TrainNetwork(int inputSize, double& data[], int Bars, int training_bars, int BarfeatureCount);//---check
void GetTrainingProgress(double &accuracy, double &progress, double &average_loss);
bool IsTraining();
double PredictNextBar(int inputSize, double& data[], int Bars, int training_bars, int BarfeatureCount);
#import
The compilation of the expert program has been successful.
But when i run the expert,I have received the following feedback
I'm sure the libsro.so is 64-bit version:
file libsro.so
libsro.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=3a93d3f2e299a0ffed5e86d747a1b79bf016d650, not stripped
Some components of CUDA, such as NCCL, cannot run on Windows, so the. so file is an important attempt.
So, how can i use .so file in my expert?