简体   繁体   English

如何使用C ++中的C99样式数组函数签名来最佳地调用函数

[英]How to best call functions with C99-style array function signatures from C++

I'm writing some code in C++ that needs to call a library written in C99. 我正在用C ++编写一些代码,需要调用用C99编写的库。 This library uses C99-style array declarations with the static keyword in its function parameters. 该库在其函数参数中使用C99样式的数组声明和static关键字。 Ie, as such: 即,如此:

void my_func(int n, int my_ints[static n]);

However, when including the headers of this library in my C++ project, the compiler (clang) throws an warning when using the -pedantic flag: 但是,在我的C ++项目中包含此库的标头时,编译器(clang)在使用-pedantic标志时会发出警告:

> g++ -pedantic -c my_code.cpp
In file included from my_code.cpp:
./my_c_lib.h: warning: variable length arrays are a C99 feature [-Wvla-extension]
void my_func(int n, int my_ints[static n]);

What is the correct/best way to call the C library in this case? 在这种情况下,调用C库的正确/最佳方法是什么? Besides turning off the vla-extension warning, is there some way around it that does not involve rewriting the library's headers or writing an intermediate C wrapper? 除了关闭vla-extension警告之外,还有一些解决方法,不涉及重写库的头文件或编写中间C包装器吗?

Minimal working example: 最小的工作示例:

extern "C" {
    void my_func(int n, int my_ints[static n]);
}

int main()
{
    int* some_ints = new int[10];
    my_func(10, some_ints);
    delete[] some_ints;
    return 0;
}

The truth is that C++ simply does not have VLAs that are nearly as powerful as the C99 ones, and it will likely never do; 事实上,C ++根本就没有像C99那样强大的VLA,它可能永远不会做; the advances that are being made to include VLAs into the language are so heavily restricted that they are pretty much useless. 将VLA纳入语言所取得的进步受到严格限制,以至于它们几乎无用。

That said, your best bet is likely to write some wrappers for the library functions that you actually use, which expose interfaces of the style 也就是说,您最好的选择是为您实际使用的库函数编写一些包装器,这些包装器会公开该样式的接口

void my_func_wrap(int n, int* my_ints);

These would be implemented in a C99 file like so: 这些将在C99​​文件中实现,如下所示:

void my_func_wrap(int n, int* my_ints) {
    my_func(n, my_ints);
}

Both the C header and the file with the implementations can be auto-generated from your library headers as the change is next to trivial. C头和带有实现的文件都可以从库头自动生成,因为更改是琐碎的。 Now you can call the wrappers from your C++ code without any type conflict. 现在,您可以从C ++代码中调用包装器,而不会发生任何类型冲突。


A second possible approach would be to write script that strips the contents of all [] brackets from the library headers, and use that instead. 第二种可能的方法是编写脚本,从库头中剥离所有[]括号的内容,然后使用它。 This would work perfectly, because even in C99 the declaration 这将完美地工作,因为即使在C99声明

void my_func_wrap(int n, int my_ints[static n]);

decays into 衰败成

void my_func_wrap(int n, int* my_ints);

This is the reason why I didn't need any cast in the wrapper function above (I know this sounds insane, but it's the truth). 这就是我在上面的包装函数中不需要任何强制转换的原因(我知道这听起来很疯狂,但这是事实)。 It's just your C++ compiler that does not like the first syntax variant. 它只是你的C ++编译器,不喜欢第一个语法变体。

is there some way around it that does not involve rewriting the library's headers or writing an intermediate C wrapper? 是否有一些方法不涉及重写库的标题或编写中间C包装?

Sure, you can just enclose the whole c header within the extern statement: 当然,您可以将整个c标头括在extern语句中:

extern "C" {
    #include "my_c_lib.h"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM