Why is my parameter passed by reference not modified within the function? - c++

I have got a C function in a static library, let's call it A, with the following interface :
int A(unsigned int a, unsigned long long b, unsigned int *y, unsigned char *z);
This function will change the value of y an z (this is for sure). I use it from within a dynamic C++ library, using extern "C".
Now, here is what stune me :
y is properly set, z is not changed. What I exactly mean is that if both are initialized with a (pointed) value of 666, the value pointed by y will have changed after the call but not the value pointed by z (still 666).
when called from a C binary, this function works seamlessly (value
pointed by z is modified).
if I create a dummy C library with a function having the same prototype, and I use it from within my dynamic C++ library, it works very well. If I re-use the same variables to call A(..), I get the same result as before, z is not changed.
I think that the above points show that it is not a stupid mistake with the declaration of my variables.
I am clearly stuck, and I can't change the C library. Do you have any clue on what can be the problem ?
I was thinking about a problem on the C/C++ interface, per instance the way a char* is interpreted.
Edit : I finally found out what was the problem. See below my answer.

It looks like a difference between the the way your C library and C++ compiler is dealing with long longs. My guess is that it is that the C library is probably pre C89 standard and actually treating the 64bit long long as a 32bit long. Your C++ library is handling it correctly and placing 64bits on the call stack and hence corrupting y and z. Maybe try calling the function through *int A(unsigned int a, unsigned long b, unsigned int *y, unsigned char z), and see what you get.
Just a thought.

This is one of those questions where there's nothing obviously wrong from what you've described, yet things aren't working the way you expect.
I think you should edit your post to give a lot more information in order to get some sensible answers. In particular, let's start with:-
What platform is this code for:
Windows, linux, something embedded
or ...?
What compiler is the C
static library built with?
What
compiler is the C++ dynamic library
built with?
What compiler is the C
which can successfully call the
library built with?
Do you have a
source-level debugger? If so, can
you step into the C code from the
C++.
Unless you're wrong about A always modifying the data pointed to by Z, the only likely cause of your problem is an incompatibility between the parameter passing conventions . The "long long" issue may be a hint that things are not as they seem.
As a last resort, you could compare the disassembled C++ calling code (which you say fails) and the C calling code (which you say succeeds), or step through the CPU instructions with the debugger (yes, really - you'll learn a good skill as well as solving the problem)

As far as I know, long long is not part of standard C++, maybe that is the source of your problem.

dunno. Try to debug-step into A and see what happens (assembly code alert!)

Maybe you can wrap the original function in a C library that you call from your C++ library?
Based on your points 2 and 3, it seems like this could work.
If it doesn't, it gives you another debug point to find more clues - see which of your libraries the failure first pops up in, and check why 2 and 3 work, but this doesn't - what is the minimal difference?
You could also try to examine the stack that is set up by your function call in each case to check if the difference is here -- considering different calling conventions.

Step 1: Compare the pointers y and z passed from the C++ side with those received by the C function.
P.S. I don't want to sound obvious, but just double-checking here. I suppose when you say that z is modified just fine when called from a C binary, you mean that the data where z is pointing is modified just fine. The pointers y and z themselves are passed by value, so you can't change the pointers.

Another wild guess: are you sure you're linking against the right instance of the function in your C library? Could it be that there are several such functions available in your libraries? In C the linker doesn't care about the return type or the parameter list when deciding how to resolve a function -- only the name is important. So, if you have multiple functions with the same name...
You could programmatically verify the identity of the function. Create a C library that calls your function A with some test parameters and that works fine and that prints the pointer to function A. Link the library into your C++ app. Then print the pointer to the original A function as seen from the C++ code and compare the pointer with that seen by your C library when invoked in the same process.

Again, an obvious one, but who knows... Are you sure the C function you're invoking is stateless, meaning its output depends only on its inputs? If the function isn't stateless, then it might be that the "hidden" state is responsible for the different behavior (not changing the data pointed to by z) of the function when invoked from your C++ app.

First of all, I am very grateful to everyone for your help.
Thanks to the numerous ideas and clues you gave me, I have been able to finally sort out this problem. Your advices helped me to question what I took for granted.
Short answer to my problem : The problem was that my C++ library used an old version of the C library. This old version missed the 4th argument. As a consequence, the 4th argument was obviously never changed.
I am a bit ashamed now that I realised this was the problem. However, I was misslead by the fact that my code was compiling fine. This was due to the fact that the C++ library compiled against the correct version of the C lib, but at runtime it used the old version statically linked with another library that I was using.
C++ Lib (M) ---> dyn C++ lib (N) ---> C lib (P) v.1.0
|
------> C lib (P) v.1.1
(N) is a dynamic library which is statically linked with (P) version 1.0.
The compiler accepted the call from (M) to the function with 4 arguments because I linked against (P) version 1.1, but at runtime it used the old version of (P).
Feel free to edit this answer or the question or to ask me to do so.

In your C++ program, is the prototype declared with extern "C"?

Related

Wrong data type for free() in Fortran

I've been asked to use a library provided here and I was following the instructions to build it in Windows, those are located here.
Now I downloaded Intel Parallel Studio XE as requested and did everything as in the instructions but there's a problem inside the code that I can't figure out completely how to solve it. The compiler says Error #6362: The data type(s) of the argument(s) are invalid..
The lines that give trouble are both the same: call free(adr(n))
And the declaration of adr(n) is what I don't know if it is correct or not since I haven't touched FORTRAN 77 in a while. It is: adr(n) = malloc(length*ipa) where ipa and length are properly defined but I don't know if adr(n) is already defined somewhere else in the header files. Should I just add a declaration at the top (I heard FORTRAN needs declarations at the top) or should I do something else? What I know is that adr(n) should be length*ipa bytes but not if it should be a specific type or not, and I don't remember how to do something along the lines of char * adr = (char *) malloc(length*ipa); as I would do in C.
This was asked and answered at https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/801638 The source being used declared the variable as integer*8 (nonstandard), but a 32-bit build was being done. Since the Intel compiler treats malloc and free as intrinsics, it detected the mismatch.
In Fortran when you pass an array to a subroutine you do not include an index. By passing adr(n) you are only passing the nth element of adr to the subroutine. You most likely want to pass the whole array like this:
call free(adr)
If this does not do it, please post a Minimal, Complete, and Verifiable example.
Welcome to stackoverflow. I suggest you take the tour. and learn how to ask good questions.

Teensy/Arduino Library compilation errors

I'm currently writing a library application for my Teensy using the Arduino IDE and so far, it has been straight forward enough to do. I have however come across a bit of an odd compilation error that I just can't seem to get my head around. My library includes the well known IRRemote Library in order for me to create what is almost a wrapper library in order to be more specific into the way I need to interact with the IR Remote library. The issue I'm having is with one of the IR Remote library functions:
void sendRaw(const unsigned int buf[],unsigned int len, unsigned int);
Although this may seem like a straight forward function to use, the issue i have is with the first argument to the function. I have tried all various ways to pass something to this function paramater but whatever I do, it simply will not compile. Currently i have set a variable
unsigned int bufferToSend[5] = {1,2,3,4,5}; // data is just for example purposes
when i try to call
sendRaw(bufferToSend, 5, 38); // Values are just for example purposes
i get a compiler error of
undefined reference to `IRsend::sendRaw(unsigned int const*, unsigned int, unsigned int)'
Interestingly, if i call the same function directly from inside the Arduino .ino file rather than via my library call, the code compiles and runs perfectly well. Am I missing something blatantly obvious?
With the help of 'Some programmer dude', I was able to resolve this issue. As it was quite rightfully pointed out, I wasn't actually linking against the external library from within my library. having worked with library linking previously, I know this is absolutely fundamental, however with Arduino and its nature, it compiles libraries that are linked against "on-the-go" when you include from the Arduino script and therefore i fell victim to thinking it would be the same in a custom library. I came across a very good write-up of my exact problem below that provides an excellent explanation to some of the Arduino "smoke and mirrors" magic and how to get round the issue I've faced here.
Advanced Arduino – Including Multiple Libraries In Your Project

Pass complex numbers to and from a DLL in LabVIEW

I am trying to interface this C++ code -- which implements functions necessary to calculate a Voigt line shape -- with LabVIEW (I'm currently running LV2009). I successfully compiled the code into a DLL, and I set up the Call Library Function Node to point to the DLL. However, the function expects a vector of type complex double and returns a vector of type complex double. Complex double is not, however, one of my choices for data type when setting up the function prototype.
Unfortunately, I do not speak C/C++, so I don't have any idea how I would go about modifying the code to get and return real doubles only. I have compiled the code into a MEX file to use with MATLAB, and pass complex numbers in and out with no problem, so I know the code works.
Is there a way to trick LabVIEW 2009 into passing complex numbers in and out of DLL functions? If not, will I gain this ability if I upgrade to the newest release? If not, is there a good basic guide to C++ that will teach me how to modify the function to accept and return the real and imaginary parts as separate vectors?
LabVIEW doesn't allow interfacing with C++ code, only C (or if it's C++, it has to have the extern "C" declaration and use Plain Old Types).
I see that your library has C wrappers, but they use the new C99 complex type, which LabVIEW doesn't understand.
However LabVIEW can pass complex data type to a function, to see how it's done open the example named "Call DLL.vi" and select complex data-type to see function prototype and VI. Your chance might be that the C99 complex has the same binary representation than the LabVIEW one. I didn't dig for the info, but it might be very possible.
If it's the case, go to church and be grateful to your Lord, and use the C wrapper to interface to it.
If it's not, find a tutorial about making a DLL for your compiler, it's not difficult, just takes time. The DLL will take two double for each complex, and make the appropriate call to the real function.

c++ DLL\static library name issue

I have problem that I am completely dumbfounded by and am hopping someone can point me in the right direction.
I have a DLL which has a static library linked in. In the DLL I have a function with the following signature and beginning:
CellMatrix BasisSwapFlows(double spread, const std::string & convention, int startDate, int endDate, bool forceEOM, const CellMatrix & returnSide, bool explode)
CashFlow::Vector flows(basisSwapFlows(spread, getBasisSwapConvention(convention), XLDate(startDate), XLDate(endDate), forceEOM));
....
In there I call a function from the static library with the signature:
CashFlow::Vector basisSwapFlows(double spread, const BasisSwapConvention & convention, const XLDate & startDate, const XLDate & endDate, bool forceEOM)
When I compile and run this in release mode then during the call to the static lib, the first parameter (spread) seems to be uninitilized. However, at the call site (in the DLL) it clearly is. This does not happen in Debug Mode. Also, if before the call to the static lib I make a copy of the argument i.e.:
double spread_loc(spread);
CashFlow::Vector flows(basisSwapFlows(spread_loc, getBasisSwapConvention(convention), XLDate(startDate), XLDate(endDate), forceEOM));
....
and pass that, the problem does not occur. Finally, if I modify the name of the static lib function to say basisSwapFlows_v2 the problem again goes away. However, reordering the parameters does nothing.
I'm using the VS2010 C++ compiler. Please let me know if there is any other info I can provide.
Edit: I also discovered that this problem goes away when I turn off optimization in the release build in both libraries. In fact, just disabling optimization in the DLL makes the problem go away.
Edit 2: Also discovered that just turning off Whole Program Optimization but leaving each project of Full Optimization resolves the problem.
Edit 3: Leaving all optimization on but taking the parameter by const ref also fixes the problem.
This very well could be an issue of using different versions of the stl. When you use runtime c++ libraries it is crucial that the same compiler with the same options was used in the client and linked library. Is it possible that you are calling the debug version of the library with the release version of the client or visa versea
The DLL and the static library must be compiled under the same conditions, that is memory alignment (byte, word, long), calling conentions (which is probably satisfied here) and same type lengthes (for example int might take 4 bytes on one compiler/switches and 2 bytes on another).

Function pointers and unknown number of arguments in C++

I came across the following weird chunk of code.Imagine you have the following typedef:
typedef int (*MyFunctionPointer)(int param_1, int param_2);
And then , in a function , we are trying to run a function from a DLL in the following way:
LPCWSTR DllFileName; //Path to the dll stored here
LPCSTR _FunctionName; // (mangled) name of the function I want to test
MyFunctionPointer functionPointer;
HINSTANCE hInstLibrary = LoadLibrary( DllFileName );
FARPROC functionAddress = GetProcAddress( hInstLibrary, _FunctionName );
functionPointer = (MyFunctionPointer) functionAddress;
//The values are arbitrary
int a = 5;
int b = 10;
int result = 0;
result = functionPointer( a, b ); //Possible error?
The problem is, that there isn't any way of knowing if the functon whose address we got with LoadLibrary takes two integer arguments.The dll name is provided by the user at runtime, then the names of the exported functions are listed and the user selects the one to test ( again, at runtime :S:S ).
So, by doing the function call in the last line, aren't we opening the door to possible stack corruption? I know that this compiles, but what sort of run-time error is going to occur in the case that we are passing wrong arguments to the function we are pointing to?
There are three errors I can think of if the expected and used number or type of parameters and calling convention differ:
if the calling convention is different, wrong parameter values will be read
if the function actually expects more parameters than given, random values will be used as parameters (I'll let you imagine the consequences if pointers are involved)
in any case, the return address will be complete garbage, so random code with random data will be run as soon as the function returns.
In two words: Undefined behavior
I'm afraid there is no way to know - the programmer is required to know the prototype beforehand when getting the function pointer and using it.
If you don't know the prototype beforehand then I guess you need to implement some sort of protocol with the DLL where you can enumerate any function names and their parameters by calling known functions in the DLL. Of course, the DLL needs to be written to comply with this protocol.
If it's a __stdcall function and they've left the name mangling intact (both big ifs, but certainly possible nonetheless) the name will have #nn at the end, where nn is a number. That number is the number of bytes the function expects as arguments, and will clear off the stack before it returns.
So, if it's a major concern, you can look at the raw name of the function and check that the amount of data you're putting onto the stack matches the amount of data it's going to clear off the stack.
Note that this is still only a protection against Murphy, not Machiavelli. When you're creating a DLL, you can use an export file to change the names of functions. This is frequently used to strip off the name mangling -- but I'm pretty sure it would also let you rename a function from xxx#12 to xxx#16 (or whatever) to mislead the reader about the parameters it expects.
Edit: (primarily in reply to msalters's comment): it's true that you can't apply __stdcall to something like a member function, but you can certainly use it on things like global functions, whether they're written in C or C++.
For things like member functions, the exported name of the function will be mangled. In that case, you can use UndecorateSymbolName to get its full signature. Using that is somewhat nontrivial, but not outrageously complex either.
I do not think so, it is a good question, the only provision is that you MUST know what the parameters are for the function pointer to work, if you don't and blindly stuff the parameters and call it, it will crash or jump off into the woods never to be seen again... It is up to the programmer to convey the message on what the function expects and the type of parameters, luckily you could disassemble it and find out from looking at the stack pointer and expected address by way of the 'stack pointer' (sp) to find out the type of parameters.
Using PE Explorer for instance, you can find out what functions are used and examine the disassembly dump...
Hope this helps,
Best regards,
Tom.
It will either crash in the DLL code (since it got passed corrupt data), or: I think Visual C++ adds code in debug builds to detect this type of problem. It will say something like: "The value of ESP was not saved across a function call", and will point to code near the call. It helps but isn't totally robust - I don't think it'll stop you passing in the wrong but same-sized argument (eg. int instead of a char* parameter on x86). As other answers say, you just have to know, really.
There is no general answer. The Standard mandates that certain exceptions be thrown in certain circumstances, but aside from that describes how a conforming program will be executed, and sometimes says that certain violations must result in a diagnostic. (There may be something more specific here or there, but I certainly don't remember one.)
What the code is doing there isn't according to the Standard, and since there is a cast the compiler is entitled to go ahead and do whatever stupid thing the programmer wants without complaint. This would therefore be an implementation issue.
You could check your implementation documentation, but it's probably not there either. You could experiment, or study how function calls are done on your implementation.
Unfortunately, the answer is very likely to be that it'll screw something up without being immediately obvious.
Generally if you are calling LoadLibrary and GetProcByAddrees you have documentation that tells you the prototype. Even more commonly like with all of the windows.dll you are provided a header file. While this will cause an error if wrong its usually very easy to observe and not the kind of error that will sneak into production.
Most C/C++ compilers have the caller set up the stack before the call, and readjust the stack pointer afterwards. If the called function does not use pointer or reference arguments, there will be no memory corruption, although the results will be worthless. And as rerun says, pointer/reference mistakes almost always show up with a modicum of testing.