将 std::vector<double> 从 C++ 包装到 C 以用于 Swift
wrapping std::vector<double> from C++ to C for use in Swift
我想在 Swift 中使用一个用 C++ 编写的程序。我已经阅读并理解了如何按照 http://www.swiftprogrammer.info/swift_call_cpp.html.[=15 中的描述进行编织和包裹的说明=]
然而,现实生活更复杂,我没有C++经验。我在 C++ 头文件中有以下代码。
namespace Fft {
void transform(std::vector<double> &real, std::vector<double> &imag);
}
我有两个问题:
- C语言的函数声明怎么写?我不知道 C 中 vector 的等价物是什么。
- C 中命名空间的含义是什么?
您可以编写一些使用 C
兼容类型的桥接函数来调用 C++
函数。这是非常未经测试的代码,只是为了让您了解您可以做什么:
namespace Fft {
void transform(std::vector<double> &real, std::vector<double> &imag);
}
extern "C" {
struct complex_vector
{
void* real;
void* imag;
};
complex_vector create_complex_vector(size_t size)
{
complex_vector cv;
cv.real = new std::vector<double>(size);
cv.imag = new std::vector<double>(size);
return cv;
}
void complex_vector_push_back(complex_vector cv, double real, double imag)
{
reinterpret_cast<std::vector<double>*>(cv.real)->push_back(real);
reinterpret_cast<std::vector<double>*>(cv.imag)->push_back(imag);
}
void complex_vector_reserve(complex_vector cv, size_t size)
{
reinterpret_cast<std::vector<double>*>(cv.real)->reserve(size);
reinterpret_cast<std::vector<double>*>(cv.imag)->reserve(size);
}
void complex_vector_resize(complex_vector cv, size_t size)
{
reinterpret_cast<std::vector<double>*>(cv.real)->resize(size);
reinterpret_cast<std::vector<double>*>(cv.imag)->resize(size);
}
void fill_complex_vector(complex_vector cv, double* real, double* imag)
{
auto v_real = reinterpret_cast<std::vector<double>*>(cv.real)->data();
auto v_imag = reinterpret_cast<std::vector<double>*>(cv.imag)->data();
auto v_size = reinterpret_cast<std::vector<double>*>(cv.real)->size();
std::copy(real, real + v_size, v_real);
std::copy(imag, imag + v_size, v_imag);
}
void fft_transform(complex_vector cv)
{
Fft::transform(*reinterpret_cast<std::vector<double>*>(cv.real), *reinterpret_cast<std::vector<double>*>(cv.imag));
}
double* complex_vector_real_array(complex_vector cv)
{
return reinterpret_cast<std::vector<double>*>(cv.real)->data();
}
double* complex_vector_imag_array(complex_vector cv)
{
return reinterpret_cast<std::vector<double>*>(cv.imag)->data();
}
size_t complex_vector_size(complex_vector cv)
{
return reinterpret_cast<std::vector<double>*>(cv.imag)->size();
}
void destroy_complex_vector(complex_vector cv)
{
delete reinterpret_cast<std::vector<double>*>(cv.real);
delete reinterpret_cast<std::vector<double>*>(cv.imag);
}
} // extern "C"
如果您将其编译为 C++
,extern "C" {}
块将生成它,因此您可以从 C
.
调用这些函数
您可以编写一个 C
程序,例如:
complex_vector cv = create_complex_vector(1024);
// fill the vector
for(int i = 0; i < complex_vector_size(cv); ++i)
complex_vector_push_back(cv, 0.2 * i, 0.4 * i);
// call the transform
fft_transform(cv);
double* real = complex_vector_real_array(cv);
double* imag = complex_vector_imag_array(cv);
size_t size = complex_vector_size(cv);
// use your transformed data here ...
destroy_complex_vector(cv);
注意: 完全未经测试的代码。
我想在 Swift 中使用一个用 C++ 编写的程序。我已经阅读并理解了如何按照 http://www.swiftprogrammer.info/swift_call_cpp.html.[=15 中的描述进行编织和包裹的说明=]
然而,现实生活更复杂,我没有C++经验。我在 C++ 头文件中有以下代码。
namespace Fft {
void transform(std::vector<double> &real, std::vector<double> &imag);
}
我有两个问题:
- C语言的函数声明怎么写?我不知道 C 中 vector 的等价物是什么。
- C 中命名空间的含义是什么?
您可以编写一些使用 C
兼容类型的桥接函数来调用 C++
函数。这是非常未经测试的代码,只是为了让您了解您可以做什么:
namespace Fft {
void transform(std::vector<double> &real, std::vector<double> &imag);
}
extern "C" {
struct complex_vector
{
void* real;
void* imag;
};
complex_vector create_complex_vector(size_t size)
{
complex_vector cv;
cv.real = new std::vector<double>(size);
cv.imag = new std::vector<double>(size);
return cv;
}
void complex_vector_push_back(complex_vector cv, double real, double imag)
{
reinterpret_cast<std::vector<double>*>(cv.real)->push_back(real);
reinterpret_cast<std::vector<double>*>(cv.imag)->push_back(imag);
}
void complex_vector_reserve(complex_vector cv, size_t size)
{
reinterpret_cast<std::vector<double>*>(cv.real)->reserve(size);
reinterpret_cast<std::vector<double>*>(cv.imag)->reserve(size);
}
void complex_vector_resize(complex_vector cv, size_t size)
{
reinterpret_cast<std::vector<double>*>(cv.real)->resize(size);
reinterpret_cast<std::vector<double>*>(cv.imag)->resize(size);
}
void fill_complex_vector(complex_vector cv, double* real, double* imag)
{
auto v_real = reinterpret_cast<std::vector<double>*>(cv.real)->data();
auto v_imag = reinterpret_cast<std::vector<double>*>(cv.imag)->data();
auto v_size = reinterpret_cast<std::vector<double>*>(cv.real)->size();
std::copy(real, real + v_size, v_real);
std::copy(imag, imag + v_size, v_imag);
}
void fft_transform(complex_vector cv)
{
Fft::transform(*reinterpret_cast<std::vector<double>*>(cv.real), *reinterpret_cast<std::vector<double>*>(cv.imag));
}
double* complex_vector_real_array(complex_vector cv)
{
return reinterpret_cast<std::vector<double>*>(cv.real)->data();
}
double* complex_vector_imag_array(complex_vector cv)
{
return reinterpret_cast<std::vector<double>*>(cv.imag)->data();
}
size_t complex_vector_size(complex_vector cv)
{
return reinterpret_cast<std::vector<double>*>(cv.imag)->size();
}
void destroy_complex_vector(complex_vector cv)
{
delete reinterpret_cast<std::vector<double>*>(cv.real);
delete reinterpret_cast<std::vector<double>*>(cv.imag);
}
} // extern "C"
如果您将其编译为 C++
,extern "C" {}
块将生成它,因此您可以从 C
.
您可以编写一个 C
程序,例如:
complex_vector cv = create_complex_vector(1024);
// fill the vector
for(int i = 0; i < complex_vector_size(cv); ++i)
complex_vector_push_back(cv, 0.2 * i, 0.4 * i);
// call the transform
fft_transform(cv);
double* real = complex_vector_real_array(cv);
double* imag = complex_vector_imag_array(cv);
size_t size = complex_vector_size(cv);
// use your transformed data here ...
destroy_complex_vector(cv);
注意: 完全未经测试的代码。