How to modify content of the original variable whi

2020-02-12 08:19发布

问题:

There is an existing API function which does only allow the plugin(DLL) to receive three parameters and perform some action:

int ProcessMe(int nCommand, unsigned int wParam, long lParam);

Now, from the main program(exe), would like to pass two variables to the plugin, and require plugin to modify their content, and main program will read them again, to perform some task.

My question is, from the above function, can I perform this, without changing the function parameters?

Example:

int ProcessMe(int nCommand, unsigned int wParam, long lParam)
{
  // modify the parameters//
  return 0;
}

int main()
{
  BOOL bSave = TRUE;
  int nOption = 0;
  ProcessMe(0, (unsigned int)(&bSave), (long)(&nOption));
  if(FALSE==bSave)
    printf("bSave is modified!");
  return 1;
}

回答1:

Place the variables to modify in a struct and pass the pointer to the sturuct to the plug in:

struct MyStruct
{
    BOOL bSave;
    int nOption;
};

int ProcessMe(int nCommand, unsigned int wParam, long lParam)
{
    ((MyStruct*)lParam)->nOption = ...;
    return 0;
}

Use it like this:

int main()
{
  MyStruct struct;
  struct.bSave = TRUE;
  struct.nOption = 0;
  ProcessMe(0, 0, (long)(&struct));
  if(FALSE==struct.bSave)
    printf("bSave is modified!");
  return 1;
}

Strictly speaking this is undefined behavior. You need to check, whether it works on your platform.

Note: I used a struct here, because this way you can also pass more variables or larger variables such as double to the function.



回答2:

No, there's no way to do that.

Passing by value means copies of the original ones are created. In the method scope, you will have no information about the original variables.

You need to either pass by reference or by value.



回答3:

Compiling for 32 bits platform you could cast to pointer the parameter:

#include <stdio.h>
typedef int BOOL;
#define FALSE 0
#define TRUE 1

int ProcessMe(int nCommand, unsigned int wParam, long lParam)
{
  // cast to match what you passed in
  *((BOOL*)wParam) = FALSE;
  return 0;
}

int cast_arguments_main(int, char **)
{
  BOOL bSave = TRUE;
  int nOption = 0;
  ProcessMe(0, (unsigned int)(&bSave), (long)(&nOption));
  if(FALSE==bSave)
    printf("bSave is modified!");
  return 1;
}

On a 64 bits platform the compiler complains about the impossibility to represent the pointer:

cast_arguments.cpp:17:37: error: cast from ‘BOOL*’ to ‘unsigned int’ loses precision

I had to change the unsigned int wParam parameter declaration to unsigned long wParam, and similar change at call point: ProcessMe(0, (unsigned long)(&bSave), (long)(&nOption)); but then you could simply declare the right type for your parameter, to be BOOL *. Thus feasibility depends on your target machine architecture...



回答4:

Try this... it is POSSIBLE!!!

include

int ProcessMe(int nCommand, unsigned int wParam, long lParam)

{

int *nCommand_ptr = (int*)nCommand;
unsigned int *wParam_ptr = (unsigned int*)wParam;
long *lParam_ptr = (long*)lParam;
*nCommand_ptr = 10;
*wParam_ptr = 10;
*lParam_ptr = 10;
return 0;

}

int main(){

int nCommand = 5;
unsigned int wParam = 5;
long lParam = 5;
printf("\n %d %u %lu",nCommand,wParam,lParam);
ProcessMe((int)&nCommand,(unsigned int)&wParam,(long)&lParam);
printf("\n %d %u %lu",nCommand,wParam,lParam);
return 0;

}

Output:

$>g++ passbyref.cc

$>./a.out

5 5 5

10 10 10$>