How to define a pointer to an array of complex numbers ?

8 次查看(过去 30 天)
I have created an array of 10 complex numbers and initialized all elements to (1.0 +1.0i). I would like to define a pointer to the array "complex_array" inorder to pass that as an input argument to a c function. The function in the shared library has "_Complex float * v" as the argument type, which has been converted to "s_C_float_complexPtr" by the matlab loadlibrary(). Can this be achieved using libpointer() ? If yes, what is the type of the pointer ? Or is there any other way ?
array = zeros(1, 10, 'single');
complex_array = complex(complex(array, single(1.0)) + single(1.0));
dataptr = libpointer('s_C_float_complexPtr', complex_array);
calllib('lib','cmplx_mean_removal', dataptr, 10);
The above code throws the following error,
A structure is required.
Error in libpointer (line 21)
ptr=lib.pointer(varargin{:});
Note:
  1. Here is the content of ‘complex_array’ when I print it,
complex_array =
1×10 single row vector
Columns 1 through 8
1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i 1.0000 + 1.0000i
Columns 9 through 10
1.0000 + 1.0000i 1.0000 + 1.0000i
2. Here is the signature of the c function, (uses standard complex notation from “complex.h”)
void cmplx_mean_removal( _Complex float * v, uint32_t len);
Would appreciate any inputs. Thank you.
  1 个评论
Jerome Almon
Jerome Almon 2023-12-4
编辑:Jerome Almon 2023-12-4
Based on the suggestion from this link, I tried to make the real and imaginary values interleaved.
https://uk.mathworks.com/matlabcentral/answers/349479-pass-complex-number-to-shared-library
array = zeros(1, 10, 'single');
complex_array = complex(complex(array, single(1.0)) + single(1.0));
complex_array = [real(complex_array(:))';imag(complex_array(:))'];
dataptr = libpointer('s_C_float_complexPtr', complex_array);
calllib('lib','cmplx_mean_removal', dataptr, 10);
but I get the same error.

请先登录,再进行评论。

回答(1 个)

Sameer
Sameer 2024-3-26
编辑:Sameer 2024-3-26
Hi Jerome,
From my understanding, you are trying to interface MATLAB with a C library function that requires an input argument of type ‘ _Complex float * ‘. You have encountered an issue when attempting to pass a MATLAB array of complex numbers to this C function using ‘libpointer()’.
The error you're encountering suggests that MATLAB is having trouble interpreting the complex array in the format expected by the C function through the libpointer mechanism, especially since MATLAB's complex number representation doesn't directly map to C's ‘_Complex float’ type.
Given the constraints and the error message, it appears that there might be a misalignment in how MATLAB handles complex data when interacting with C libraries. MATLAB represents complex numbers in a format that is not directly compatible with C's ‘_Complex‘ type, which expects the real and imaginary parts interleaved in memory.
Your second approach, where you manually interleave the real and imaginary parts, is on the right track. However, the issue might be with how you're creating the libpointer. When you interleave the real and imaginary parts, the data is no longer recognized by MATLAB as complex. Instead, it's seen as a real array twice the length of the original complex array, with alternating real and imaginary parts.
Here's how you can adjust your approach:
  1. Ensure Correct Data Interleaving: You've already interleaved the data correctly, but ensure it's in a single contiguous array suitable for passing to the C function.
  2. Correctly Define the libpointer Type: Since you've now effectively got an array of float (or single in MATLAB terms) rather than a complex array, you should define your libpointer with a type that reflects this.
Here's a refined version of your code:
% Original complex array
array = zeros(1, 10, 'single');
complex_array = complex(array + single(1.0), array + single(1.0));
% Interleaving real and imaginary parts
interleavedArray = zeros(1, numel(complex_array)*2, 'single');
interleavedArray(1:2:end) = real(complex_array); % Real parts
interleavedArray(2:2:end) = imag(complex_array); % Imaginary parts
% Create libpointer with correct type
dataptr = libpointer('singlePtr', interleavedArray);
% Call the library function
calllib('lib','cmplx_mean_removal', dataptr, 10);
'singlePtr' is used as the type for ‘libpointer’ since you're passing a single-precision, floating-point array (interleaved real and imaginary parts) to the C function. This is assuming your C function is indeed expecting an array of float representing the complex numbers in interleaved format.
‘interleavedArray’ is prepared to exactly match the memory layout expected by the C function for ‘_Complex float * ‘.
For additional information, please refer to the link below:
I hope this helps!
Sameer

类别

Help CenterFile Exchange 中查找有关 Call C from MATLAB 的更多信息

产品


版本

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by