Home > Blockchain >  How to implement fold expression in case of extern "C"
How to implement fold expression in case of extern "C"

Time:03-24

I am a beginner in red team development.Trying to implement hellsgate in C . Simply put, in this program, the C program directly calls the function from the asm file.

The function in asm file:

    HellDescent PROC
        mov r10, rcx
        mov eax, wSystemCall
        syscall
        ret
    HellDescent ENDP

The function in C:

//define
extern HellDescent();
//call
HellDescent(-1,...);

In C , this gives the error: “Too many arguments to function.”After referring to the material, I found the way of Fold expressions. When I used the method in the demo to create the function.


template <class... Args>
extern "C" int HellDescent(Args&&... args){}

Visual Studio prompted me: “linkage-specification-is-not-allowed."

I tried to search for information to solve but no results. Can anyone tell how to fix it.

CodePudding user response:

In C extern HellDescent(); declares a function with no arguments, regardless of linkage type. extern "C" doesn't change rules of language as a popular belief states, it only changes way how names are represented. There is no "function with undeclared count of arguments" in C . You have to declare possible overloads and ditch "C" linkage as it doesn't support overloads. The way how you had defined template it isn't compatible with "C" calls because it would require decoration of names, aka name mangling, to resolve overloads.

It's unclear what are use cases here, but it might be possible to create some adapter, a C function which would call asm-function if there is a limited set arguments or refactor whole thing to take a data structure containing all arguments in portable form. C is a high-level language and assembler approach of "call whatever address we can and feed it whatever we want as arguments" doesn't work in it because of vast variety of implementations supported.

CodePudding user response:

(I'm assuming that this is an XY problem with "X" being "how do I declare a function with arbitrary arguments in C " and "Y" being "how can I use a variadic template, which I call 'fold expression', to declare a function with C linkage".)

You don't need folds or templates, you need to use the appropriate syntax.

In C , the parameter list () is the empty parameter list; it is equivalent to (void).
In C, you need to explicitly write (void) for a function that does not accept any arguments.

In C, () means "any number of arguments of any types", and is equivalent to (...).
In C , you need to explicitly write (...) for a function that takes arbitrary arguments.

So,

extern "C" int HellDescent(...);

should work fine.

Also note that functions are extern by default, so you can use the normal incantation

#ifdef __cplusplus
extern "C"
#endif

int HellDescent(...);

and get a valid and equivalent declaration for both languages.

  •  Tags:  
  • c
  • Related