Note that there are some explanatory texts on larger screens.

plurals
  1. POCall Method Without Specifying Parameters
    primarykey
    data
    text
    <p>this is sort of difficult to explain but I'll do my best. I will pose the question as it applies to one method, but know that this solution should be generic enough to apply to any possible method given. Consider the following:</p> <p>I have a regular old global method:</p> <pre><code>void MyMethod( int a, int b ) { cout &lt;&lt; a &lt;&lt; " , " &lt;&lt; b &lt;&lt; endl; } </code></pre> <p>I have another method that is to call this method.</p> <pre><code>void Caller( void* method, void* data, int size ) { // convert method to some function calling convention // call the method here with the given data } </code></pre> <p>This caller should be able to call any method internally without knowing how many parameters it takes and what their data types are. All it really knows about the method is the address to the method and the size, in bytes, of the entire parameter list.</p> <p>So simply stated, how can I call an arbitrary method and pass it an arbitrary amount of data for it to interpret as parameters?</p> <p>Essentially, without modifying <code>MyMethod</code>, how do I push the <code>void* data</code> into the registers used as parameters from within <code>Caller</code>? Is this possible? I'm not concerned about safety or portability.</p> <p>Before <code>Caller</code> is called, I have an array of void*'s that point to the data that can be passed to the internally called method. I'm not sure if this is even the best approach to this problem.</p> <p>I'm writing a scripting system, in essence, that can call methods from the script. So the methods are stored in a lookup table, where each is given a string name, and have a void* to the actual method to be called. At execution time I know how many parameters the method expects and what types the parameters are (the types are stored as metadata when the method is given an entry in the lookup table). This allows me to convert the string values that are the parameters in the script to the values they actually should be (using a custom conversion system). But the converter returns a void*, because you call it as such:</p> <pre><code>string s = "123456"; void* result = Converter::Convert( "string*", "int", &amp;s ); </code></pre> <p>I can guarantee that the value stored in <code>result</code> is actually of the requested type (if a converter for this type-pair exists), but have no way of casting to this type, as the type name is merely provided as a string. This makes the converter flexible and really type-indifferent. But it makes handling the values that it returns complicated. So in script I would make a call like this:</p> <pre><code>MyMethod( 111, 222 ) </code></pre> <p>This would then be parsed, the method name would be used to look up the method address, and the converter would then convert the values it finds into the expected datatypes, but return them as <code>void*</code>. Then a call to Caller would be made, passing in the method address, arguments it has converted, as an array of bytes, and the size of the array of parameter data, in bytes. It is at this point that I need to call that method and pass these parameters. Again, I cannot modify the existing methods it is calling.</p> <p>I've looked into assembly to pass this data in, but it seems that you have to either make the method naked to read parameters directly in assembly or do something else, and I've never really worked in assembly before. Although if the solution lies in assembly, I'm fine with learning some.</p> <p>Please don't downvote for ambiguity; if you need more context I can provide it. Just comment. I really appreciate it.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload