copying function pointer throws error in one function pointer - casting

I have cjson code (https://github.com/kbranigan/cJSON/blob/master/ ) , it compiles well when I compile on the linux pc .
but when I compile for some embedded platform it throws error at
if (!hooks) { /* Reset hooks */
cJSON_malloc = mem_alloc; // its equal to gcc malloc for the embedded compiler
cJSON_free = mem_free; // its equal to gcc free
}
The error is Undefined reference to mem_alloc , and mem_free
but if I call the function like below
char* data = (char*) mem_alloc(32);
it compiles well ..
compiler is xtensa compiler(xt-xcc)
isn't it right way to assign ?

Related

How to run a Fortran program within GNU Octave?

I want to run a Fortran program within Octave. I would like to do this for automation purposes and use Octave for all the data processing.
Is it possible to run a Fortran program from octave using cygwin, if so, could you provide me some pointers along that direction?
Moreover, I have a gfortran compiler installed in my system, Is there a way I could make use of it to complete my task mentioned above?
Furthermore, I tried to use mex to perform the same:
mckoctfile --mex HelloWorld.f
I got the following error after trying the mex approach:
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\rajan\AppData\Local\Temp/oct-qur1RF.o: in function `hi': C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_st_write'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_transfer_character_write'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_st_write_done'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\rajan\AppData\Local\Temp/oct-qur1RF.o: in function `main':C:\Tech Stuff\Fortran Programs/HelloWorld.f:6: undefined reference to `_gfortran_set_args'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:6: undefined reference to `_gfortran_set_options'
collect2.exe: error: ld returned 1 exit status
warning: mkoctfile: building exited with failure sta
How do I resolve this error to move forward?
Obviously your particular use-case may be a lot more complex than this, but here's a simple example to get you started (or to help you decide whether it's worth going down that route at all...)
Let's start with a simple octfile which performs simple integer addition, no fortran involved for now.
// in: simple_addition.cpp
#include <octave/oct.h>
DEFUN_DLD (simple_addition, args, ,"Add two integers via C++")
{
octave_value retval = args(0).int_value() + args(1).int_value();
return retval;
}
Compile:
mkoctfile -c simple_addition.cpp # compiles a simple_addition.o file
mkoctfile -o simple_addition simple_addition.o # links .o file to named output file
In octave:
octave:1> simple_addition(1,2)
ans = 3
Now let's put this aside for a minute, and see how we might call a fortran-defined function from pure c++. First let's create a simple integer addition function:
! in fortran_addition.f90
function fortran_addition(a,b) result(Out)
integer, intent(in) :: a,b ! input
integer :: Out ! output
Out = a + b
end function fortran_addition
and compile it using gfortran:
gfortran -c fortran_addition.f90 # creates fortran_addition.o
You can see (e.g. using nm fortran_addition.o) that the generated object contains a reference to a symbol under the name fortran_addition_ (note the added underscore at the end).
Now let's create a normal (i.e. non-octave-related) c++ wrapper program which calls the function defined via this symbol:
// in generic_fortran_addition_wrapper.cpp
#include <iostream>
extern "C" { int fortran_addition_( int *, int * ); }
int main() {
int a = 1, b = 2, fortran_result;
fortran_result = fortran_addition_( &a, &b );
std::cout << a << " + " << b << " = " << fortran_result << std::endl;
}
compile:
g++ -c generic_fortran_addition_wrapper.cpp
g++ -o addints generic_fortran_addition_wrapper.o fortran_addition.o
./addints # outputs `1 + 2 = 3` on the terminal
Now we have all the ingredients to create an octfile that wraps a fortran function:
// in fortran_addition_wrapper.cpp
#include <octave/oct.h>
extern "C" { int fortran_addition_( int *, int *); }
DEFUN_DLD (fortran_addition_wrapper, args, ,"Add two integers via fortran")
{
int a, b, fortran_result;
a = args(0).int_value();
b = args(1).int_value();
fortran_result = fortran_addition_( &a, &b );
octave_value retval(fortran_result);
return retval;
}
compile with mkoctfile:
mkoctfile -c fortran_addition_wrapper.cpp
mkoctfile -o fortran_addition_wrapper fortran_addition_wrapper.o fortran_addition.o
and then in octave:
octave:1> fortran_addition_wrapper(1,2)
ans = 3
Having said all this, obviously if you have a fully defined fortran program, rather than just linkable functions, and you have a running compiled executable on your system, then you can skip all the above 'formalities' and just call your executable via the system() command from octave. Obviously in this scenario it's up to you to pass the data in an octave-agnostic way ... but presumably if you have a standalone fortran executable, then presumably it already has a way of reading input data from the operating system.
EDIT as per the comments below, I've been reminded that I got side-tracked and answered the question that was asked in the comments to the original question, and forgot to address the error messages in the original question. As mentioned in my comment there, mkoctave is a generic wrapper to the gnu compiler collection. Those messages do not sound specific to octave, but rather that the compiler/linker complains that you're missing the fortran runtime libraries that define these basic functions.

Confusion about pointer values being compile-time constatns

In C++, it is possible for pointer values to be compile-time constants. This is true, otherwise, non-type template parameters and constexpr won't work with pointers. However, as far as I know, addresses of functions and objects of static storage are known (at least) at link-time rather than compile-time. Following is an illustration:
main.cpp
#include <iostream>
template <int* p>
void f() { std::cout << p << '\n'; }
extern int a;
int main() {
f<&a>();
}
a.cpp
int a = 0;
I'm just wondering how the address of a could possibly be known when compiling main.cpp. I hope somebody could explain this a little to me.
In particular, consider this
template <int* p, int* pp>
constexpr std::size_t f() {
return (p + 1) == (pp + 7) ? 5 : 10;
}
int main() {
int arr[f<&a, &b>()] = {};
}
How should the storage for arr be allocated?
PLUS: This mechanism seems to be rather robust. Even when I enabled Randomized Base Address, the correct output is obtained.
The compiler doesn't need to know the value of &a at compile time any more than it needs the value of function addresses.
Think of it like this: the compiler will instantiate your function template with &a as a parameter and generate "object code" (in whatever format it uses to pass to the linker). The object code will look like (well it won't, but you get the idea):
func f__<funky_mangled_name_to_say_this_is_f_for_&a>__:
reg0 <- /* linker, pls put &std::cout here */
reg1 <- /* hey linker, stuff &a in there ok? */
call std::basic_stream::operator<<(int*) /* linker, fun addr please? */
[...]
If you instantiate f<b&>, assuming b is another global static, compiler does the same thing:
func f__<funky_mangled_name_to_say_this_is_f_for_&b>__:
reg0 <- /* linker, pls put &std::cout here */
reg1 <- /* hey linker, stuff &b in there ok? */
call std::basic_stream::operator<<(int*) /* linker, fun addr please? */
[...]
And when your code calls for calling either of those:
fun foo:
call f__<funky_mangled_name_to_say_this_is_f_for_&a>__
call f__<funky_mangled_name_to_say_this_is_f_for_&b>__
Which exact function to call is encoded in the mangled function name.
The generated code doesn't depend on the runtime value of &a or &b.
The compiler knows there will be such things at runtime (you told it so), that's all it needs. It'll let the linker fill in the blanks (or yell at you if you failed to deliver on your promise).
For your addition I'm afraid I'm not familiar enough about the constexpr rules, but the two compilers I have tell me that this function will be evaluated at runtime, which, according to them, makes the code non-conforming. (If they're wrong, then the answer above is, at least, incomplete.)
template <int* p, int* pp>
constexpr std::size_t f() {
return (p + 1) == (pp + 7) ? 5 : 10;
}
int main() {
int arr[f<&a, &b>()] = {};
}
clang 3.5 in C++14 standards conforming mode:
$ clang++ -std=c++14 -stdlib=libc++ t.cpp -pedantic
t.cpp:10:10: warning: variable length arrays are a C99 feature [-Wvla-extension]
int arr[f<&a, &b>()];
^
1 warning generated.
GCC g++ 5.1, same mode:
$ g++ -std=c++14 t.cpp -O3 -pedantic
t.cpp: In function 'int main()':
t.cpp:10:22: warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[f<&a, &b>()];
As far as I know, the variables of static storage and functions are stored simply as symbols/place holders in the symbol table while compiling. It is in the linking phase when the place holders are resolved.
The compiler outputs machine code keeping the placeholders intact. Then the linker replaces the placeholders of the variables / functions with their respective memory locations. So in this case too, if you just compile main.cpp without compiling a.cpp and linking with it, you are bound to face linker error, as you can see here http://codepad.org/QTdJCgle (I compiled main.cpp only)

MEX compilation error

I'trying to compile the c code with mex for MATLAB 2013a 64 under win7 64
http://www.cs.cornell.edu/People/tj/svm%5Flight/svm_perf.html
According to info from this site the SVMPerf MATLAB interface was done by O Luaces
but only for Linux and MACos and it don't compile under windows
http://www.aic.uniovi.es/~oluaces/Oscars_Home_Page/Personal.html
for this i installed gnumex to have access to gcc for MATLAB and this is ok.
then I compiled with mex and created object files for all involved c programs according
to make file from SVMPerf.
I also compiled mex_interface.cpp file which was used for MATLAB interface under LINUX.
However when I try to link all files I'm getting following error related to my_malloc
svm_learn_main.obj:svm_learn_main.c:(.text+0x470): first defined here
svm_struct_main.obj:svm_struct_main.c:(.text.startup+0x0): multiple definition of
`main'
svm_learn_main.obj:svm_learn_main.c:(.text.startup+0x0): first defined here
Cannot export mexFunction: symbol not defined
mex_interface.obj:mex_interface.cpp:(.text+0x94): undefined reference to
`my_malloc(unsigned long long)'
mex_interface.obj:mex_interface.cpp:(.text+0x218): undefined reference to
`my_malloc(unsigned long long)'
C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.9.0/../../../../x86_64-w64-mingw32
/bin/ld.exe: mex_interface.obj: bad reloc address 0x0 in section `.pdata'
collect2.exe: error: ld returned 1 exit status
link command: gcc -shared C:\Users\KRZYSZ~1\AppData\Roaming\MATHWO~1\MATLAB\R2013a
\gnumex\mex.def -o svm_perf_classify.mexw64 -LC:\Users\KRZYSZ~1\AppData\Roaming
\MATHWO~1\MATLAB\R2013a\gnumex -s mex_interface.obj my_malloc.obj svm_learn_main.obj
svm_learn.obj svm_common.obj svm_hideo.obj svm_struct_learn.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj svm_struct_api.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj -llibmx -llibmex
-llibmat
I believe it points to this code. my_malloc compiles OK. Any idea ??
void create_argc_argv(const mxArray *options,int *argc,char **argv[]) {
// convert the matlab string of options into a CLI-like input (argc and argv)
*argc=1;
mwSize buflen = mxGetN(options)*sizeof(mxChar)+1;
char *buf = mxMalloc(buflen);
// Copy the string data into buf
mxGetString(options, buf, buflen);
// and separate in argv[]
char **ap, **argv_ptr=(char **)my_malloc(MAX_ARGVS*sizeof(char *));
argv_ptr[0]="OLR";
for (ap = (argv_ptr+1); (*ap = strsep(&buf, " \t")) != NULL;)
if (**ap != '\0') {
(*argc)++;
if (++ap >= &argv_ptr[MAX_ARGVS])
break;
}
// 'buf' shouldn't be freed, since it is converted to the different 'argv[i]'
// by setting to '\0' the tabs and white spaces between options
// (this trick was taken from the 'strsep' man page)
// so, we don't make mxFree(buf);
*argv=argv_ptr;
}
my mex command looks like this
mex -largeArrayDims -DWIN -output svm_perf_classify mex_interface.cpp
svm_learn_main.obj svm_learn.obj svm_common.obj svm_hideo.obj svm_struct_learn.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj svm_struct_api.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj
It looks like the issue you have isn't MEX related, as the main function is declared more than once. Which makes it hard for the compiler to know where to start running the code. If you have public functions you want to use in svm_learn_main or svm_struct_main, you'll want to separate those from the files containing the main function.
mex -largeArrayDims -DWIN -output svm_perf_classify mex_interface.cpp
svm_perf_classify does not have a source file extension(.c or .cpp or other), so it's considered a executable by compiler.

CUDA C compile error: new operator is not allowed in global function

I have the following CUDA C code. When trying to compile it, I get the following error:
function new/delete operator is not allowed in global function.
I have been able to compile this code in the past without error. What could be the problem?
__global__ void kern(float *P, ... a bunch of other variables)
{
...
W = new float[M];
...
delete[] W;
}
Just now I figured out: in compilation, need to add
-arch sm_30
to build the code for compuite capability 3.0.

c++ using of iconv on Windows with Mingw compiler

Good time of day!
I compiled this code with g++ 4.7.2 on Ubuntu successfully, but I have problems with compiling it on Windows with Mingw.
Simplified Code:
size_t string_length=some_size;
char arr_symb[string_length+1];
char *outputde=arr_symb;
iconv_t type=iconv_open("UTF-8","WINDOWS-1251");
char output[some_size];
char *p1=arr_symb;
char *p2=output;
if ( iconv(type, &p1,&string_length, &p2, &output_length ) == -1 )// here
// is mistake, it doesn't like pointers p1 and p2 but I wonder why
log_info("something went wrong");
On Linux with G++ it can be compiled and works fine as it should. With Mingw I get errors:
I wonder, if it works fine with g++ , why does mingw treat it like it's mistaken?
Thanks in advance!
ADDITION
My Mingw version is 4.4.0
GCC version is 4.7.2
Thanks all for your attention, problem is solved, but it's all strange to me (it's still unclear )
Although the function has such prototype,
With MinGW it should be called so:
So, the problem is that input string for MinGW should be passed as constant (also it doesn't have such prototype).
See these declarations:
int a[10];
int* b = malloc(10 * sizeof(int));
Looks and feels the same, but:
A pointer to an array of ints (*b) is NOT the same as an array of ints (a)! So a pointer to an array (*) is also not the same as a pointer to a pointer (**)!
The dereferencing for the pointer needs one more level!