2013-07-02 76 views
0

我有接收一個函數指針和具有該功能的認定中和每說參數的XML字符串的功能的C++函數:調用使用函數指針

void CallFunction(void * pFuncion, std::string xmlFuncionDef) 
{ 

} 

裏面的上述功能, xmlFunctionDef包含由pFunction指向的函數的定義。例如,數字參數,每個參數的類型和參數:

<Function ParamCount="3" ReturnType="int"> 
    <Params> 
    <Param type="int" DefaultValue="None" PassBy="Value"/> 
    <Param type="double" DefaultValue="None" PassBy="Referenc"/> 
    <Param type="char*" DefaultValue="None" PassBy="Pointer"/> 
    </Params> 

    <Arguments> 
    <Arg Value="3" /> 
    <Arg Value="29.5" /> 
    <Arg Value="Hello World" /> 
    </Arguments> 
</Function> 

現在我該如何調用此函數?我應該使用_asm嗎?

任何幫助將不勝感激。

+0

沒有ü意味着'無效CallFunction(無效(* pFuncion)(無效),的std :: string xmlFuncionDef)'? – hit

+1

您問「如何調用該功能」。但是第一部分已經不清楚了:你如何接收指向該函數的指針? 'void * pFuncion'是void類型的指針,這不是指向函數的指針。 – ondrejdee

+0

如果您的代碼應該在特定的體系結構上運行,那麼您可以使用內聯彙編並將參數壓入堆棧,然後調用該函數。但是,然後你的函數負責以正確的順序從堆棧中獲取參數。無論如何,你的問題沒有明確的定義。更具體一些,並舉例說明。 –

回答

0

據我所知,函數指針不能有靈活的參數 - 你必須確切地告訴函數將接收什麼樣的參數。在您的例子:

void (*pFunc)(int,double,char*) 

你可以,當然,使用無效*作爲唯一的參數,然後把該變性 內部:

void (*pFunc)(void*) 

,但我相信這將是一個邀請一團糟。

0

要做到這一點,最好的方法是將註冊該函數的代碼位作爲params和return類型的模板。然後你可以把它分開,並返回一個lambda,它知道如何解析XML並調用函數。真正的hacky概念證明[它不處理可變參數(硬編碼爲2),使用字符串而不是xml,假定類型是默認可構造的,不處理參考或移動,並作爲練習留給讀者]是:

#include <string> 
#include <functional> 
#include <sstream> 
#include <iostream> 
#include <stdexcept> 

template<class FIRST, class SECOND, class RETURN_TYPE> 
std::function<RETURN_TYPE(std::string const&)> RegisterFunction(
    RETURN_TYPE(func)(FIRST f, SECOND s)) 
{ 
    auto copy = *func; 
    return[copy](std::string const& str)->RETURN_TYPE 
    { 
     std::istringstream inStream(str); 
     FIRST f; 
     inStream >> f; 
     if(inStream.fail()) 
     { 
      throw std::runtime_error("Couldn't parse param one"); 
     } 
     SECOND s; 
     inStream >> s; 
     if(inStream.fail()) 
     { 
      throw std::runtime_error("Couldn't parse param two"); 
     } 
     // can check if inStream is eof here for consistency 
     return copy(f, s); 
    }; 
} 

std::string MyFunc(float f, std::string s) 
{ 
    std::ostringstream os; 
    os << "MyFunc called with float " << f << " and string " + s; 
    return os.str(); 
} 


int main() 
{ 
    auto wrapper = RegisterFunction(MyFunc); 

    // Now try to call it 
    std::cout << wrapper("42.0 HelloWorld") << std::endl; 

    // Try to call it with an invalid string 
    try 
    { 
     std::cout << wrapper("This isn't the number you are looking for"); 
    } 
    catch(...) 
    { 
     std::cout << "Failed to call function" << std::endl; 
    } 
} 

輸出:

MyFunc called with float 42 and string HelloWorld 
Failed to call function