Pelles C forum

C language => Beginner questions => Topic started by: rkorko on August 13, 2012, 11:56:04 PM

Title: how is that done?
Post by: rkorko on August 13, 2012, 11:56:04 PM
hi,

i hope someone can explain how that would be done. i want to wrap a call to int _cprintf(const char * restrict format, ...); in to a dll that calls it.

ex.:

_declspec(dllexport) int __stdcall conprint(const char * restrict format, ...) {
return _cprintf(format, ...);  <------ ?????????? how do i call this function???
}


any help would be greatly appreciated.

thanks

henry
Title: Re: how is that done?
Post by: CommonTater on August 14, 2012, 12:56:51 AM
In MyDLL.c ... 

_declspec(dllexport) int _stdcall function(...

In MyDLL.h...

#pragma lib "MyDLL.lib"  // autocreated library header for mydll

_declspec(dllimport) int _stdcall function(...


In your code...

#include "MyDLL.h"

x = function(...
Title: Re: how is that done?
Post by: rkorko on August 14, 2012, 08:11:45 AM
thanx for you reply.
but what i ment, was how does the call inside the function look like.

return _cprintf(format, ...);  <------ ?????????? how do i call this function???

the function header gives
_declspec(dllexport) int __stdcall conprint(const char * restrict format, ...) {

and how would i call return _cprintf(format, ...);  <------ ?????????? how do i call this function??? inside the function?
maybe you can give me another helpful hint.

henry
Title: Re: how is that done?
Post by: CommonTater on August 14, 2012, 08:50:52 AM
The inner one it's just a normal function call that is linked into the DLL when you compile it, just like in an EXE.

Where you might be having a problem is that you have a function with a variable number of parameters inside a function with a variable number of parameters...  I've never had to do that one, so maybe one of the others can offer a bit of advice on how to do it.
Title: Re: how is that done?
Post by: rkorko on August 14, 2012, 08:58:03 AM
yes, but how do i call it.
i don't know the parmeters that are given to _declspec(dllexport) int __stdcall conprint(const char * restrict format, ...).

ex.: conprint("%s %d %s %s", a,b,c,d). how do i give the paramets to return _cprintf(format, ...)?
Title: Re: how is that done?
Post by: CommonTater on August 14, 2012, 09:00:09 AM
We were writing at the same time...

As I said, I've never had to do that one, so maybe one of the others can help...
Title: Re: how is that done?
Post by: rkorko on August 14, 2012, 09:02:41 AM
thank you very much anyway. i hope someone can help me.
Title: Re: how is that done?
Post by: CommonTater on August 14, 2012, 09:42:58 AM
Two thoughts...

1) Just us _cprintf() directly without the DLL wrapper.

2) You can use the standard printf() with no muss or fuss. 

Is there some reason to write such a thinly wrapped function?
Title: Re: how is that done?
Post by: rkorko on August 14, 2012, 10:10:40 AM
Quote
1) Just us _cprintf() directly without the DLL wrapper.
2) You can use the standard printf() with no muss or fuss.
Is there some reason to write such a thinly wrapped function?
unfortunately i need to export this function to another compiler/language and i need the console-output, that the other compiler doesn't have. the library (dll) is a cbtree/isam that i want to test with that compiler. testing it with pelles c has certain problems, such as somefunction(char *x, char *y). on return, x and y are not modified as they should, they retain the old values.

Title: Re: how is that done?
Post by: aardvajk on August 14, 2012, 04:09:08 PM
You can't do that. C doesn't allow it. You can use vcprintf though, which lets you forward the arguments using a va_list.


#include <stdio.h>
#include <stdarg.h>

int __cdecl conprint(const char *fmt, ...)
{
    va_list args;
    int ret = 0;

    va_start(args, fmt);
    ret = _vcprintf(fmt, args);
    va_end(args);
    return ret;
}


Note that your function has to be __cdecl instead of stdcall because your code doesn't know how many arguments its going to be called with (the number and size of arguments is required for stdcall)
Title: Re: how is that done?
Post by: CommonTater on August 14, 2012, 05:04:18 PM
Quote from: rkorko on August 14, 2012, 10:10:40 AM
testing it with pelles c has certain problems, such as somefunction(char *x, char *y). on return, x and y are not modified as they should, they retain the old values.

I can see where it might be a problem in your case, but generally this is a good thing... In C variables have a "scope" marked by { } in which you can affect them, outside of their scope variables with the same names are not affected.  For example:

#include <stdio.h>

int func(int x)
  {
   x += 3;
   printf("%d\n",x);  //prints 13
   return x;
  }

int main (void)
  {
   int x = 10;
   func(x); 
   printf("%d\n",x);  //prints 10
   x = func(x);
   printf("%d\n",x); // prints 13
   return 0;
  }

Passing in pointers such as *x will let you modify the variable in the calling scope, but not the pointer. For example...

#include <stdio.h>

void func(int *x)
  {
   *x += 3;
   printf("%d\n",x);  //prints 13
  }

int main (void)
  {
   int x = 10;
   func(&x); 
   printf("%d\n",x);  //prints 13
   return 0;
  }

The reason this happens is that C does not know Pass By Reference. Everything is Pass By Value. When you call a C function you are passing in a copy of the variable, not the variable itself.  Even with pointers you are passing in a copy of the pointer... If you want to change the value of the pointer itself you need to pass in the address of the pointer; a pointer to a pointer... **x  ...

In C this is generally a good thing since it prevents same-name variables inside a function from accidentally affecting the overall program...

(Thanks aardvajk :D )
Title: Re: how is that done?
Post by: rkorko on August 15, 2012, 09:25:14 AM
yes - i understand now. thank you.
do you have a solution for the problem with calling a variable parameter function?