プロが教える店舗&オフィスのセキュリティ対策術

[やりたい事]
 (1)テキストファイルを読込む
   ※テキストには関数名が記述されてます。
 (2)取得した関数を実行する。

[できない事]
 (1)はできたのですが、(2)ができない。
 取得した文字列をどうやれば関数として実行できるのか、分からず悩んでます。
回答よろしくお願いします。

A 回答 (7件)

一般にムリ。



関数名が funcA, funcB, funcC のどれかであることがあらかじめわかっているなら

char* name; /* ファイルから読み取った関数名 */
if ( strcmp(name,"funcA")==0 ) { funcA(); }
if ( strcmp(name,"funcB")==0 ) { funcB(); }
if ( strcmp(name,"funcC")==0 ) { funcC(); }
    • good
    • 0

★アドバイス


・スクリプト言語でも開発しているのでしょうか?
 読み込んだ関数名の文字列と関数のポインタをセットで構造体で管理して実行する方法が
 一番良いと思いますが。
・どういう理由で読み込んだ関数を実行したいのですか?
 もうちょっと全体像が見えるような補足をお願いします。
・それでは。また。
    • good
    • 0

Windowsでしか通用しない方法ですが


関数の部分をdll化し

::LoadLiblary(dllのファイル名)

::GetProcAddress(dllのハンドル,関数名)

として関数のアドレスを取得し
その関数を実行する事は可能です。
    • good
    • 0

(1)までできた所を乗せるとよいでしょう。


#2さんが言っているものを簡単なサンプルにしました。

#include <stdio.h>
#include <string.h>

#define MAXFUNCNAMELEN (256)
#define MAXLINEBUFFLEN (1024)

//関数テーブル登録用の関数ポインタ型定義
typedef int(*PFUNC)( void );

//関数名と関数のアドレスを格納する構造体
typedef struct script{
 char funcname[MAXFUNCNAMELEN];
 PFUNC funcaddr;
}SCRIPT;

//登録する関数の宣言
int print( void );
int print2( void );

//関数名と関数アドレスのテーブル定義
const SCRIPT funclist[] = {
 { "print", print },
 { "print2", print2 },
 { "" , NULL },
};

int main( int argc, char* argv[] )
{
 int i;
 FILE *fp;
 char line[MAXLINEBUFFLEN];
 
 fp = fopen( "script.txt", "rt" );
 if( !fp ){
  return 1;
 }

 //ファイルを終わりまで読む
 while( fgets( line, MAXLINEBUFFLEN, fp) != NULL ){
  //登録されている関数名すべてと比較する
  for( i=0; funclist[i].funcaddr!=NULL; i++ ){
   //一行の文字列が関数名と一致したか
   if(!strncmp( line, funclist[i].funcname, strlen(funclist[i].funcname))){
    //一致したらその関数を実行
    funclist[i].funcaddr();
   }
  }
 }

 fclose( fp );
 return 0;
}

int print( void )
{
 printf("print呼び出し\n");
 return 0;
}

int print2( void )
{
 printf("print2呼び出し\n");
 return 0;
}

読み込むテキストの内容
print
print
print
print2
print

<<このサンプルの制限>>
・一行に一関数しか書けず他の文字も掛けない
・引数は渡せない
・インデントが全角スペースです

このサンプルは最もテキトーに作られたものです。
DLLなどでプラグインできるようにすると使い勝手もよくなるでしょう。
#経験上最大の敵は引数でした。
    • good
    • 0

#4です。


下のサンプル実行して気づきましたが、
直前までの関数名が同じだと、数回実行されてしまいますね。。。
以下のようにしてください。。。

修正前
const SCRIPT funclist[] = {
 { "print", print },
 { "print2", print2 },
 { "" , NULL },
};

修正後
const SCRIPT funclist[] = {
 { "print\n", print },
 { "print2\n", print2 },
 { "" , NULL },
};

修正前
if(!strncmp( line, funclist[i].funcname, strlen(funclist[i].funcname))){

修正後
if(!strcmp( line, funclist[i].funcname )){

改行文字変換面倒だったので手を抜いたのが仇となったようです。。。
    • good
    • 0

処理系を特定するか、関数名と関数へのポインタの対応表を作るかしかありません。



処理系を特定する方法として考えられるのは...

1. CINTのようなC/C++インタプリタであれば、再帰的に実行することで実現可能かと思います。

2. すでに回答が出ているように、DLLなどの共有ライブラリを使う方法があります。

3. プログラムのシンボルテーブルを読み込ませることで、関数のアドレスを知る方法があります。

関数というのがC/C++の関数ではなく、専用のものでよいなら、独自のインタプリタ機能を持たせることで実現することも可能です。
    • good
    • 0

ret = _spawnl(_P_WAIT, ecp1, ecp1, eck1, ecpath0, ecpath1,NULL);


とします。
 昔のC言語の関数です。
VC++6.0から呼び出せます。

_spawnl
について調べてください。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!