Windows DLL 用文件初始化常量 c 字符串数组
Windows DLL initialise array of constant c strings with file
背景
我目前正在从事一个项目,为此我编写了一个 DLL 作为 Windows 驱动程序和 MATLAB 之间的接口。所有这些都运行良好,但直到最近它一直缺少某些功能的文档——本质上它允许将命令字符串发送到 FPGA,并且所有这些命令都需要记录。
这可以使用 PDF 等来完成,但我还想要一种将文档集成到 DLL 本身的方法 - 因此可以使用 'lookup command' 等函数。无论如何,我继续以我最满意的方式实施了这个。
基本上我有一个结构(见下文),可以从函数返回一个指向该结构的指针,以便可以访问文档。调用者提供指向其中之一的指针地址,然后用常量全局数组中的条目地址更新该地址。
typedef struct {
CONST CHAR * commandString;
ULONG commandStringLen;
CONST CHAR * documentationString;
ULONG documentationStringLen;
CONST CHAR * commandParameters;
ULONG commandParametersLen;
} COMMAND_DOCS;
#define STRING_LEN(a) a,(sizeof(a)-1)
#define NEWGROUP "\n "
#define NEWENTRY "\n "
#define NEWLINE "\n"
#define ENDTITLE "\n----------------------------------------\n"
CONST COMMAND_DOCS CommandDocs[] = {
//-----
#define COMMAND_xyz_GROUP_INDEX_START (0)
{ STRING_LEN("ABCD"),
STRING_LEN("Something Command"
ENDTITLE"Low Queue"
NEWLINE "Description:"
NEWGROUP"The .........."
NEWLINE),
STRING_LEN(NEWGROUP"Type x:"
NEWENTRY"No Payload"
NEWLINE)
},
#define COMMAND_xyz_GROUP_LENGTH (1)
//-----
... And so on
};
这会导致大量常量字符串存储在内存中,以及一个文档结构数组,其中包含指向这些常量及其长度的指针以及良好的度量。如我所说,返回指向数组中所需元素的指针。库的调用者 API 然后可以根据需要自由制作副本或显示字符串。
目前一切正常,除了一个小问题。每当我需要更新文档时,都需要我重新编译 DLL - 因为很明显所有字符串都已编译到其中。对我来说,这不是问题,因为我可以轻松地编译它,但由于我在一所大学工作,正在开发一个供他们使用的研究平台,我希望它在我继续前进时对人们来说在未来更新时一样简单其他工作。理想情况下,如果文档需要更新 - 比如说新命令被添加到系统中,我希望无需重新编译就可以添加这些命令。
问题
所以我的问题实际上是关于执行此操作的最佳方法是什么。
目前我正在考虑从文件中加载文档,无论是在加载 DLL 时,还是在调用搜索功能时。目前数组中有#defines 来分隔索引(标识命令组),但这些可以替换为由文件中的数据初始化的变量。
我可以选择 XML 之类的东西并解析它来填充结构,但我的一部分认为如果它更简单一些,在外面的世界会更容易理解,但我想我仍然需要一些方法来识别条目之间的界限等。
想法?
请注意,DLL 主要是 C 语言——所有 API 都是 C 接口,但在内部它是 C++,因为我一直在其他部分使用 类。我不介意使用哪个只要它与C接口兼容。
我暂时离开了这个问题,因为它并不紧急,但在过去几周又回来了。我发现我需要向 DLL 添加更多设置和可配置的东西,这使得我之前使用的方法绝对不可用。
基本上正如@PhilWilliams 在评论中建议的那样,我已经使用 XML 文件来配置所有内容。现在有一些 API 必须在加载指定要加载的 XML 文件位置的库后立即调用。然后 DLL 将解析 XML 文件并填充大量内部结构。我现在没有使用#defines 和常量字符串,而是有一个结构数组,其中指向已解析字符串的指针与以前#defines 的索引一起定位。
在查看 Whosebug 并找到有关简单 XML 解析器的各种建议后,我选择了 TinyXML2,因为这意味着我无需为分配和释放内存而头疼对于许多文档字符串,因为它在内部处理。
背景
我目前正在从事一个项目,为此我编写了一个 DLL 作为 Windows 驱动程序和 MATLAB 之间的接口。所有这些都运行良好,但直到最近它一直缺少某些功能的文档——本质上它允许将命令字符串发送到 FPGA,并且所有这些命令都需要记录。
这可以使用 PDF 等来完成,但我还想要一种将文档集成到 DLL 本身的方法 - 因此可以使用 'lookup command' 等函数。无论如何,我继续以我最满意的方式实施了这个。
基本上我有一个结构(见下文),可以从函数返回一个指向该结构的指针,以便可以访问文档。调用者提供指向其中之一的指针地址,然后用常量全局数组中的条目地址更新该地址。
typedef struct {
CONST CHAR * commandString;
ULONG commandStringLen;
CONST CHAR * documentationString;
ULONG documentationStringLen;
CONST CHAR * commandParameters;
ULONG commandParametersLen;
} COMMAND_DOCS;
#define STRING_LEN(a) a,(sizeof(a)-1)
#define NEWGROUP "\n "
#define NEWENTRY "\n "
#define NEWLINE "\n"
#define ENDTITLE "\n----------------------------------------\n"
CONST COMMAND_DOCS CommandDocs[] = {
//-----
#define COMMAND_xyz_GROUP_INDEX_START (0)
{ STRING_LEN("ABCD"),
STRING_LEN("Something Command"
ENDTITLE"Low Queue"
NEWLINE "Description:"
NEWGROUP"The .........."
NEWLINE),
STRING_LEN(NEWGROUP"Type x:"
NEWENTRY"No Payload"
NEWLINE)
},
#define COMMAND_xyz_GROUP_LENGTH (1)
//-----
... And so on
};
这会导致大量常量字符串存储在内存中,以及一个文档结构数组,其中包含指向这些常量及其长度的指针以及良好的度量。如我所说,返回指向数组中所需元素的指针。库的调用者 API 然后可以根据需要自由制作副本或显示字符串。
目前一切正常,除了一个小问题。每当我需要更新文档时,都需要我重新编译 DLL - 因为很明显所有字符串都已编译到其中。对我来说,这不是问题,因为我可以轻松地编译它,但由于我在一所大学工作,正在开发一个供他们使用的研究平台,我希望它在我继续前进时对人们来说在未来更新时一样简单其他工作。理想情况下,如果文档需要更新 - 比如说新命令被添加到系统中,我希望无需重新编译就可以添加这些命令。
问题
所以我的问题实际上是关于执行此操作的最佳方法是什么。
目前我正在考虑从文件中加载文档,无论是在加载 DLL 时,还是在调用搜索功能时。目前数组中有#defines 来分隔索引(标识命令组),但这些可以替换为由文件中的数据初始化的变量。
我可以选择 XML 之类的东西并解析它来填充结构,但我的一部分认为如果它更简单一些,在外面的世界会更容易理解,但我想我仍然需要一些方法来识别条目之间的界限等。
想法?
请注意,DLL 主要是 C 语言——所有 API 都是 C 接口,但在内部它是 C++,因为我一直在其他部分使用 类。我不介意使用哪个只要它与C接口兼容。
我暂时离开了这个问题,因为它并不紧急,但在过去几周又回来了。我发现我需要向 DLL 添加更多设置和可配置的东西,这使得我之前使用的方法绝对不可用。
基本上正如@PhilWilliams 在评论中建议的那样,我已经使用 XML 文件来配置所有内容。现在有一些 API 必须在加载指定要加载的 XML 文件位置的库后立即调用。然后 DLL 将解析 XML 文件并填充大量内部结构。我现在没有使用#defines 和常量字符串,而是有一个结构数组,其中指向已解析字符串的指针与以前#defines 的索引一起定位。
在查看 Whosebug 并找到有关简单 XML 解析器的各种建议后,我选择了 TinyXML2,因为这意味着我无需为分配和释放内存而头疼对于许多文档字符串,因为它在内部处理。