Problem converting Matlab code to C standalone executable using Matlab Coder
Show older comments
Hello, I am trying to convert a very simple Matlab program (connect two input strings together) to a C standalone executable using Matlab Coder.
The m file I have is:
function r = connect(a,b) %#codegen
assert(isa(a,'char'));
assert(isa(b,'char'));
r = [a,b];
The main.c I have is:
#include <stdio.h>
#include <stdlib.h>
#include "connect.h"
#include "connect_initialize.h"
#include "connect_terminate.h"
int main(int argc, char *argv[])
{
connect_initialize();
printf("Result is %s\n", connect(argv[1],argv[2]));
connect_terminate();
return 0;
}
The error message I got is:
26 C:\C\connect\main.c(16) : warning C4047: 'function' : 'char_T' differs in levels of indirection from 'char *'
27 C:\C\connect\main.c(16) : warning C4024: 'connect' : different types for formal and actual parameter 1
28 C:\C\connect\main.c(16) : warning C4047: 'function' : 'char_T' differs in levels of indirection from 'char *'
29 C:\C\connect\main.c(16) : warning C4024: 'connect' : different types for formal and actual parameter 2
I'd really appreciate it if somebody can give me a hint. Thanks.
3 Comments
Walter Roberson
on 3 Sep 2012
What does connect.h give as being the function signature for connect()? I suspect you will find that it is not expecting char* such as you will get from argv[1] and argv[2]
Hank
on 3 Sep 2012
Prachi Singh
on 25 Mar 2015
I am also facing a problem while matlab to c conversion. I am working on ECG Analysis using Pan-Tompkins Algorithm I have a function defined as function [ ecg_m,qrs_amp_raw,qrs_i_raw,delay]= pan_tompkin(ecg,fs,gr) but after converting to c using matlab coder I am getting a function void pan_e(const emxArray_real_T *ecg, real_T fs, real_T gr, emxArray_real_T *ecg_m, real_T *delay)
and there is no a mention of qrs_amp_raw,qrs_i_raw which are mainly needed for further processing. Can someone suggest why this problem is occurring?
Accepted Answer
More Answers (1)
Walter Roberson
on 3 Sep 2012
0 votes
That C function signature corresponds to passing a single character to "a" and a single character to "b" and (I think) passing in a pointer to an array of exactly 2 characters to write "r" into.
Note: C expects "strings" to be null terminated, and so a C string with 2 usable characters would need 3 positions, the third for the 0 that terminates it. But it is not an error to construct a character array with only exactly 2 non-zero characters, as long as you do not treat it as a string. But in that code, you do try to treat it as a string, as you want to pass the result directly to printf(). One problem with that -- the function does not return anything and instead writes into an address you pass in in the third parameter.
I do not know why the code is expecting single characters instead of character arrays -- the assert() you are using would normally be suitable for character arrays. You probably need to do something different to alert codegen that you are not working with scalars. I speculate that you will need to initialize r to an array that is the maximum size of the string you will return.
15 Comments
Hank
on 3 Sep 2012
Walter Roberson
on 3 Sep 2012
Those strcpy() will not help. argv[1] and argv[2] are going to be pointers to C strings (null-terminated array of characters). Copying them won't make them any more valid. Copying only part of them might be useful in some cases, but if you were copying only part of them then you would use strncpy() instead of strcpy().
connect() shows up in the .h file as void, meaning it does not return anything. You cannot pass the result of connect() to anything. Instead you have to pass in the address of an array that will receive the result. You can then pass the address of the array into printf(). When you are sizing the array remember to take into account the terminating null that printf() will need. You can do that by passing connect() an array one longer than the maximum result it will write, and writing 0 into the final position after the call returns; or you can pass connect() an array exactly the right size, and then use strncpy() to copy it into a space one larger (and write 0 into the final position.)
To initialize r to the maximum size inside connect, experiment with
r = repmat(' ', 1, 20); %adjust the 20 to your needs
before you do the r = [a,b]
Hank
on 3 Sep 2012
Walter Roberson
on 3 Sep 2012
#define Result_Size 5
char string_c[Result_Size];
connect(string_a,string_b, &string_c);
string_c[Result_Size - 1] = 0;
printf("Result is %s\n", string_c);
Hank
on 3 Sep 2012
Walter Roberson
on 3 Sep 2012
Edited: Walter Roberson
on 3 Sep 2012
Try
connect(string_a, string_b, string_c);
Depending on how the code generator handles the signal it is given through pre-allocation, you might need
connect(string_a[0], string_b[0], string_c);
Hank
on 4 Sep 2012
Walter Roberson
on 4 Sep 2012
In the case where you use r = repmat(' ', 1, 20); as the first line of connect(), please show me the connect.h that is generated.
Walter Roberson
on 4 Sep 2012
I would be curious as to whether anything would change if you were to alter the assert() to be
assert(isa(a(10),'char'));
With the code as-is, I can see what should go into r_sizes, but I have not figured out yet why r_data came out as size 8, nor how to pass in multi-character strings.
(Note: I do not have the MATLAB Coder product, so I am back-engineering from the C code.)
Hank
on 4 Sep 2012
Walter Roberson
on 4 Sep 2012
It is still expecting single characters to pass into connect(), so argv[1][0] and argv[2][0] still.
I do not know how to convince it to accept strings at the moment.
Hank
on 4 Sep 2012
Walter Roberson
on 4 Sep 2012
It appears that the following is relevant: http://www.mathworks.com/help/toolbox/eml/ug/br_jxhp.html
Hank
on 7 Sep 2012
Categories
Find more on MATLAB Coder in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!