typedef enum command_result_e {
COMMAND_OK,
COMMAND_ERROR
} command_result;
typedef command_result (command_func)(void *);
typedef enum command_id_e {
COMMAND_TEST1,
COMMAND_TEST2,
COMMAND_TEST3,
} command_id;
struct command_s {
char * name;
command_func * func;
// char * description; /* Can be used for "help" function
further in application, but not needed for examples below */
};
typedef struct command_s command_t;
示例1:
以直接的方式,就像构造的数组一样:
command_result test1_handle(void *args) {printf("Test1\r\n"); return COMMAND_OK;}
static const command_t test1 = {"Test1",
test1_handle};
command_result test2_handle(void *args) {printf("Test2\r\n"); return COMMAND_OK;}
static const command_t test2 = {"Test2",
test2_handle};
command_result test3_handle(void *args) {printf("Test3\r\n"); return COMMAND_OK;}
static const command_t test3 ={"Test3",
test3_handle};
const command_t command_list[] = {
[COMMAND_TEST1] = test1,
[COMMAND_TEST2] = test2,
[COMMAND_TEST3] = test3,
};
我认为上面的解决方案不是理想的选择,因为如果您仅考虑在某些构建中保留某些命令,则可以重复#if(def)语句。另外,正如进一步的那样,除了手动外,没有简单的方法可以其他方式对命令进行分类。
compy-pasting command_t structs in command_list感觉有些糟糕,但也许在这里,它在不需要的地方寻求完美。
示例2:
__属性__(__(__节__(“”))和链接脚本:
const command_t __attribute__((__section__(".grouped_const.begin"))) command_list_begin[0];
command_result test1_handle(void *args) {printf("Test1\r\n"); return COMMAND_OK;}
const command_t __attribute__((__section__(".grouped_const.content"))) test1 = {sizeof("Test1"), "Test1",
test1_handle, "Test 1 command."};
command_result test2_handle(void *args) {printf("Test2\r\n"); return COMMAND_OK;}
const command_t __attribute__((__section__(".grouped_const.content"))) test2 = {sizeof("Test2"), "Test2",
test2_handle, "Test 2 command."};
command_result test3_handle(void *args) {printf("Test3\r\n"); return COMMAND_OK;}
const command_t __attribute__((__section__(".grouped_const.content"))) test3 ={sizeof("Test3"), "Test3",
test3_handle, "Test 3 command."};
const command_t __attribute__((__section__(".grouped_const.end"))) command_list_end[0];
我理解,使用LD脚本修改
SECTIONS {
.grouped_const {
. = ALIGN(4) // for 32-bit systems
*(.grouped_const.begin .grouped_const.content .grouped_const.end)
. = ALIGN(4)
}
}
还有其他方法来组织这种应用结构吗?
写入功能并将其编译为.dll或.so
在文件中存储函数名称作为字符串。
使用存储的字符串在dll(左右)中添加此函数。#include <windows.h>
#include <iostream>
typedef int (*MyFunctionType)(); // Define function pointer type
void CallFunctionFromDLL(const char* dllName, const char* functionName)
{
HMODULE hModule = LoadLibraryA(dllName);
if (!hModule)
{
std::cerr << "Failed to load DLL: " << dllName << std::endl;
return;
}
FARPROC functionAddress = GetProcAddress(hModule, functionName);
if (!functionAddress)
{
std::cerr << "Failed to find function: " << functionName << std::endl;
FreeLibrary(hModule);
return;
}
// Cast and call the function
MyFunctionType myFunction = (MyFunctionType)functionAddress;
int result = myFunction(); // Call the function
std::cout << "Function returned: " << result << std::endl;
FreeLibrary(hModule); // Clean up
}
int main()
{
CallFunctionFromDLL("example.dll", "MyExportedFunction");
return 0;
}
或Linux
#include <iostream>
#include <dlfcn.h> // Required for dlopen, dlsym, dlclose
typedef int (*MyFunctionType)(); // Define function pointer type
void CallFunctionFromSO(const char* soName, const char* functionName)
{
void* handle = dlopen(soName, RTLD_LAZY);
if (!handle)
{
std::cerr << "Failed to load SO: " << dlerror() << std::endl;
return;
}
dlerror(); // Clear existing errors
void* functionAddress = dlsym(handle, functionName);
const char* error = dlerror();
if (error)
{
std::cerr << "Failed to find function: " << functionName << " - " << error << std::endl;
dlclose(handle);
return;
}
// Cast and call the function
MyFunctionType myFunction = (MyFunctionType)functionAddress;
int result = myFunction(); // Call the function
std::cout << "Function returned: " << result << std::endl;
dlclose(handle); // Clean up
}
int main()
{
CallFunctionFromSO("./libexample.so", "MyExportedFunction");
return 0;
}