Value passed from one function to another changes... Can't figure out why? - c

I have a very weird problem that I can't understand.
This is C code:
//below are the values being passed
//long numTreePeriods = 80
//double length = 0.23013698630136986
TTimeLineInfo* tlInfo = GtoTimeLineInfoNew( (long)ceil(numTreePeriods/length), /*ppy*/
0L,
1,
FALSE);
Now here's the signature of the GtoTimeLineInfoNew function called above:
__declspec(dllexport) TTimeLineInfo* GtoTimeLineInfoNew
(long minPPY, /* (I) Min # ppy before switchDate */
TDate switchDate, /* (I) If 0, ignore ppy2; only use minPPY*/
long minPPY2, /* (I) Min # ppy after switchDate */
TBoolean wholeDayTPs);
When I debug my code and step into the function with the values specified above I get:
minPPY = -1636178017
????? What could cause this type of behaviour?
Just to precise the C code is a dll I am wrapping up in C++/CLI. Nevertheless the problem seems independent from that....

I'm not certain; but my guess would be a difference between how parameters are passed to a C function vs. a C++ function. Try:
extern "C" __declspec(dllexport) TTimeLineInfo* GtoTimeLineInfoNew ...

For some reason ceil(numTreePeriods/length) was giving something very weird. So I wrote a ceil function myself to solve this problem...
UPDATE:
Like highlighted in comment by glglgl, the appropriate header was missing, hence ceil was interpreted to return an int which led to funny values...

Related

Could not find the entrypoint _pcre2_compile#40. (3260)

I have built a libpcre2-8.dll with the help of this Git Repo.
I'm now trying to access the function pcre2_compile from an ABL (Progress) program. (Progress is an old 4GL Language). I'm constantly hitting the error
Could not find the entrypoint _pcre2_compile#40. (3260)
I've already tried many things but it still doesn't work.
The Dynamic Library is 64 bit and Progress is also running in 64 bit.
In ABL (Progress) you can specify the LIBRARY-CALLING-CONVENTION but whether I set it to STDCALL or CDECL or just don't specify it, the error remains the same.
This is a snippet of the Progress ABL I'm trying to execute the function: (code comes from this Git Repo, which works, but only for 32 bit)
PROCEDURE pcre2_compile :
DEFINE INPUT PARAMETER pattern AS CHARACTER. /* const char * */
DEFINE INPUT PARAMETER options AS INTEGER. /* int */
DEFINE OUTPUT PARAMETER errcodeptr AS INTEGER. /* int * */
DEFINE OUTPUT PARAMETER errptr AS MEMPTR. /* const char ** */
DEFINE OUTPUT PARAMETER erroffset AS MEMPTR. /* int * */
DEFINE INPUT PARAMETER tableptr AS INTEGER. /* const unsigned char * */
DEFINE OUTPUT PARAMETER result AS MEMPTR. /* pcre * */
DEFINE VARIABLE libName AS CHARACTER NO-UNDO.
DEFINE VARIABLE hCall AS HANDLE NO-UNDO.
libName = get-library().
CREATE CALL hCall.
ASSIGN
hCall:CALL-NAME = "pcre2_compile"
hCall:LIBRARY = "lib/libpcre2-8.dll"
//hCall:LIBRARY-CALLING-CONVENTION = "STDCALL"
hCall:CALL-TYPE = DLL-CALL-TYPE
hCall:NUM-PARAMETERS = 6
hCall:RETURN-VALUE-DLL-TYPE = "MEMPTR".
hCall:SET-PARAMETER(1, "CHARACTER", "INPUT" , pattern ).
hCall:SET-PARAMETER(2, "LONG" , "INPUT" , options ).
hCall:SET-PARAMETER(3, "HANDLE TO LONG" , "OUTPUT", errcodeptr ).
hCall:SET-PARAMETER(4, "MEMPTR" , "OUTPUT", errptr ).
hCall:SET-PARAMETER(5, "MEMPTR" , "OUTPUT", erroffset ).
hCall:SET-PARAMETER(6, "LONG" , "INPUT" , tableptr ).
hCall:INVOKE().
ASSIGN result = hCall:RETURN-VALUE.
DELETE OBJECT hCall.
END PROCEDURE.
What am I missing?
Update: Checked with Dependency Walker and the functions seem to be visible. They do have a _8 suffix... But even when trying pcre2_compile_8 it still gives me the same error.
I think that you need to change your long integers to INT64.
Is the entrypoint externally visible/accesible?
I've used https://dependencywalker.com/ in the past to figure that out.
Does that change if you specify the ORDINAL option ?
So the problem was that the name of the entry point was "pcre2_compile_8" instead of "pcre2_compile"... Wanted to delete the question because now it looks quite dumb but leaving it anyway...

Pointer decryption function not working as intended

First of all, it is important to say that the code will be a mess, I know that and there is a reason behind the messy code, but I prefer not to specify why to avoid going off track.
This snippet of code decrypts a pointer:
//LLUNGO is long long
//PLLUNGO is long long pointer
//SCANVELOCE is __fastcall
LLUNGO SCANVELOCE DecryptPointer(PPTR_SECRET _pSecret, PLLUNGO _OldPointer)
{
_OldPointer = (PLLUNGO) PTR_ENCRYPTION_ALGORITHM(*_OldPointer, _pSecret->Segreto);
INTERO Reference = GetReferenceToPtr(_pSecret, _OldPointer);
if (PTR_BAD_REFERENCE(Reference))
QUICK_PRINT("Bad reference error.\n");
return PTR_ENCRYPTION_ALGORITHM((LLUNGO)_pSecret->Riferimenti[Reference], _pSecret->Segreto);
}
using the following macros:
#define PTR_ENCRYPTION_ALGORITHM(PTR, KEY) (~(PTR ^ KEY))
#define PTR_BAD_REFERENCE(PTR) ((-1) == (PTR))
Now the problem is when I use the macro stated below, for some reason even if I am using the right arguments it is still throwing me this error:
no instance of overloaded function "DecryptPointer" corresponds to the
arguments.
Consider that NBYTE is BYTE and REGISTRA is the register keyword.
NBYTE SCANVELOCE MFINIT(LLUNGO _FuncAddr, PMUTILATE_FUNCTION _Function)
{
if (!_FuncAddr || !_Function)
return FALSO;
SELF_PTR_DECRYPTION( _FuncAddr ); //error thrown here
SELF_PTR_DECRYPTION( _Function ); //and here too!
for (REGISTRA PNBYTE Current = (PNBYTE)_FuncAddr; ; Current--)
{
if (MF_PUSH_EBP == *Current)
{
_Function->Inizio = (LLUNGO)Current;
break;
}
}
And the SELF_PTR_DECRYPTION macro + everything else necessary for the DecryptPointer function to work:
(PTR_SECRET being a struct)
#define SELF_PTR_DECRYPTION(X) ((X) = (PTR_DECRYPTION(X)))
#define PTR_DECRYPTION(X) DecryptPointer(&PTR_SECRET_NAME, X)
#define PTR_SECRET_NAME g_PTR_SECRET
INIT(PTR_SECRET PTR_SECRET_NAME);
Again sorry for the stupidly messy code, I'm struggling too, just like everyone reading this probably will, but again there is a reason behind the mess.
The solution has been found in the comments by #yano:
you've taken me straight to macro hell. If I'm following correctly,
_FuncAddr in the SELF_PTR_DECRYPTION( _FuncAddr ); call ends up being the 2nd argument to DecryptPointer, which expects a PLLUNGO type.
However, _FuncAddr is a LLUNGO type. And if its complaining about "no
overloaded function" it sounds like you're using a C++ compiler, not
C.
Many thanks, and sorry for the absolute mess of code I presented here.

How to define block of code inside if condition

I work with old C project and should make there several changes
It has lots of macros....
The function calls are defined there as
#define myFunc(arg) myBaseFunc(arg)
bool myBaseFunc is a function, actually there are several myBaseFunc
(its a kind of polymorphism)
I need to add some check of arguments correctness to myFunc
Actually the project has :
#define checkArg(arg) {\
// lot of code
}
I can`t change checkArg implementation
1) I thought to //
/*It is not correct if I do `if(myFunc(arg))`*/
#define myFunc(arg)\
checkArg(arg)\
myBaseFunc(arg)
2)I thought to
/*It is better...but compiler doesn`t like code block `{}` inside`if(myFunc(arg))`*/
#define myFunc(arg)(\
checkArg(arg),\
myBaseFunc(arg))
Is there a workaround for this case
A possible solution is to check the arg before it is passed to the base function. That works however only if there's only a single argument.
#define myFunc(arg) myBaseFunc(checkArg(arg))
Your checkArg function(s) must be changed so that they return the same value they got as parameter, e.g.
int checkArg(int value) {
... test stuff
return value;
}
I think It is possible like this, but you need to know argument type:
int main_check_function(void* data) { // <= this type need to be type of functions.
checkArg(data);
return (myBaseFunc(data));
}
#define myFunc(arg) (main_check_function(arg))
Although as I told, it is limited to knowing type. I just added a function to project to check your code by running checkArg() and then running myBaseFunc(). This approach is simple, but it has that big drawback.

.C() returns me an empty list

I'm a beginner in R and I'm trying to load a .dll file, named dll.dll, that's written in C, into R. It seems to work, now I want to use the functions that are stored in the .dll file and I encounter problems.
I've searched for a solution or other method in manuals, here and on google. Would be very thankful if I could get a suggestion of what to use or any idea!
My code:
setwd("C:/Users/MyUser/R")
dyn.load("dll.dll")
is.loaded("DLL_FUNK")
# For some reason True with capital letters, not in lower case
output <- .C("DLL_FUNK", in9 = as.integer(7))
#output # R Crashes before I can write this.
# R Crashes
# In outdata.txt: "in-value= 139375128"
The function should return a number, 1955. But I can't seem to get to that value. What am I doing wrong?
Update with code (Fortran runned as C), this is the code in dll.dll:
subroutine dll_funk(in9)
implicit none
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!*** Declarations: variables, functions
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
integer(4) :: in9
!integer :: in9
! Definitions of variables in the external function calls
!!dec$ attributes c,alias :'dll_funk' :: dll_funk
!dec$ attributes dllexport :: dll_funk
!dec$ attributes value :: in9
open(194,file='outdata.txt')
write(194,*) 'in-value=', in9
! in9 = 1955
close(194)
end subroutine
!end function
So now when it runs, R crashes but before it writes to my file (outdata.txt) but it't not my number, maybe some kind of address...
Another question, do you recommend me to run the code with .C and from C run the Fortran code or is it better to run it with .Fortran with only Fortran code?
It seems like .Fortran have problem handling strings, or that's what I understood from: Interface func .C and .Fortran
Why did not you pass any arguments to your C function dll_function? When you use .C(), you have to pass function arguments as a list. .C() will return modified list. So, If you pass in nothing, you get nothing.
What does your C function dll_function looks like? Note that:
dll_function must be a void C function, with no return values. If this function should return something, it must return by modifying function arguments;
all function arguments of dll_function must be pointers.
Follow-up
The dll_function is only to test if I can get access to it.
You can use is.loaded() after dyn.load() to test whether you have access to the C function:
dyn.load("dll.dll")
is.loaded("dll_function") ## TRUE
Note that, is.loaded takes C function name, while dyn.load() takes .dll name. In general you can have multiple functions in a single .dll file. You can use is.loaded() to check either of them, to test whether shared library has been loaded successfully.
So if I want it to return something, I should give it an argument (of same type?)?
Yes. The other answer here does give a toy example. You can have a look at this answer I made half a month ago. At the bottom there is a summary of variable type.
When using .C, the extra arguments passed to .C are copied and passed on as pointers to the called c-function. This function can then modify the data pointer to by the pointers. The return value of the function is ignored by .C. So, you c-function should look something like:
void dll_function(int* result) {
/* Do some complicated computation that results in 1955 */
(*result) = 1955;
}
And your call from R:
.C("dll_function", integer(1))
An example with input (this calculates the sum of an integer vector; this example assumes that there are no missing values in vector):
void dll_function2(int* result, int* vector, int* length) {
int sum = 0;
for (int i = 0; i < (*length); ++i, ++vector) {
sum += (*vector)
}
(*result) = sum;
}
Called from R:
x <- c(1000, 900, 55)
.C("dll_function2", integer(1), as.integer(x), length(x))[[1]]

Is it possible to exchange a C function implementation at run time?

I have implemented a facade pattern that uses C functions underneath and I would like to test it properly.
I do not really have control over these C functions. They are implemented in a header. Right now I #ifdef to use the real headers in production and my mock headers in tests. Is there a way in C to exchange the C functions at runtime by overwriting the C function address or something? I would like to get rid of the #ifdef in my code.
To expand on Bart's answer, consider the following trivial example.
#include <stdio.h>
#include <stdlib.h>
int (*functionPtr)(const char *format, ...);
int myPrintf(const char *fmt, ...)
{
char *tmpFmt = strdup(fmt);
int i;
for (i=0; i<strlen(tmpFmt); i++)
tmpFmt[i] = toupper(tmpFmt[i]);
// notice - we only print an upper case version of the format
// we totally disregard all but the first parameter to the function
printf(tmpFmt);
free(tmpFmt);
}
int main()
{
functionPtr = printf;
functionPtr("Hello world! - %d\n", 2013);
functionPtr = myPrintf;
functionPtr("Hello world! - %d\n", 2013);
return 0;
}
Output
Hello World! - 2013
HELLO WORLD! - %D
It is strange that you even need an ifdef-selected header. The code-to-test and your mocks should have the exact same function signatures in order to be a correct mock of the module-to-test. The only thing that then changes between a production-compilation and a test-compilation would be which .o files you give to the linker.
It is possible With Typemock Isolator++ without creating unnecessary new levels of indirection. It can be done inside the test without altering your production code. Consider the following example:
You have the Sum function in your code:
int Sum(int a, int b)
{
return a+b;
}
And you want to replace it with Sigma for your test:
int Sigma(int a, int b)
{
int sum = 0;
for( ; 0<a ; a--)
{
sum += b;
}
return sum;
}
In your test, mock Sum before using it:
WHEN_CALLED: call the method you want to fake.
ANY_VAL: specify the args values for which the mock will apply. in this case any 2 integers.
*DoStaticOrGlobalInstead: The alternative behavior you want for Sum.
In this example we call Sigma instead.
TEST_CLASS(C_Function_Tests)
{
public:
TEST_METHOD(Exchange_a_C_function_implementation_at_run_time_is_Possible)
{
void* context = NULL; //since Sum global it has no context
WHEN_CALLED(Sum (ANY_VAL(int), ANY_VAL(int))).DoStaticOrGlobalInstead(Sigma, context);
Assert::AreEqual(2, Sum(1,2));
}
};
*DoStaticOrGlobalInstead
It is possible to set other types of behaviors instead of calling an alternative method. You can throw an exception, return a value, ignore the method etc...
For instance:
TEST_METHOD(Alter_C_Function_Return_Value)
{
WHEN_CALLED(Sum (ANY_VAL(int), ANY_VAL(int))).Return(10);
Assert::AreEqual(10, Sum(1,2));
}
I don't think it's a good idea to overwrite functions at runtime. For one thing, the executable segment may be set as read-only and even if it wasn't you could end up stepping on another function's code if your assembly is too large.
I think you should create something like a function pointer collection for the one and the other set of implementations you want to use. Every time you want to call a function, you'll be calling from the selected function pointer collection. Having done that, you may also have proxy functions (that simply call from the selected set) to hide the function pointer syntax.

Resources