2017-01-05 7 views
0

プリプロセッサディレクティブ(オプションのプレフィックスを追加)で関数名を動的に生成しようとしています。動的関数名 - 外部シンボルを解決できません

世代が動作し、gccがプリプロセッサ(gcc -E)の後ろにコードを出力するとき、gccは関数に正しい名前があることを伝えます。

しかし、この関数をコードで使用すると、gccは未解決の外部シンボルでエラーをスローしますか? (Link2019/Link1120)

リンカの仕組みは100%ではありませんが、理論的にはgccはプリプロセッサを実行し、すべてのライブラリをビルドします(もっと正確には最初のプロトタイプとメイン定義の後ろ)?問題ない? 特別なコンパイラオプションを追加する必要がありますか?リンク?

私の主:

#define _CRT_SECURE_NO_WARNINGS 
#define STRING_FUNCTION_PREFIX my // Defining a prefix for my string functions 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h>     // Original string functions 
#include "string.h"     // My string functions 

#define ARRAY_SIZE 50 
#define HALLO "HALLO" 
#define WELT "WELT" 

int main() 
{ 
    char src1[ARRAY_SIZE], src2[ARRAY_SIZE], dst1[ARRAY_SIZE], dst2[ARRAY_SIZE]; 
    strcpy(src1, HALLO); 
    strcpy(dst1, WELT); 
    strcpy(src2, HALLO); 
    strcpy(dst2, WELT); 

    strcat(src1, dst1); 
    mystrcat(src2, dst2); 

    return 0; 
} 

マイstring.hの

#pragma once 
#include <stdlib.h> 

#if defined STRING_FUNCTION_PREFIX 
#define FUNCTION_PASTER(ARG1,ARG2) ARG1 ## ARG2 
#define FUNCTION_EVALUATER(ARG1,ARG2) FUNCTION_PASTER(ARG1, ARG2) 
#define FUNCTION_NAME(FUNCTION) FUNCTION_EVALUATER(STRING_FUNCTION_PREFIX, FUNCTION) 
#else 
#define FUNCTION_NAME(FUNCTION) FUNCTION 
#endif 

/* 
* \brief: Adds the string from src to the destination string 
*/ 
void FUNCTION_NAME(strcat)(char *dst, char *src); 

string.hのための私のstring.c

#include "string.h" 

void FUNCTION_NAME(strcat)(char *dst, char *src) 
{ 
    int counter = 0, offset = 0; 
    while (dst[offset] != '\0') 
    { 
     offset++; 
    } 

    dst[offset + counter] = src[counter]; 
} 

出力-E

1> #line 11 "d:\\string.h" 
1> 
1> 
1> 
1> 
1> void mystrcat(char *dst, char *src); 
でコンパイル

ありがとうございました!

+0

実際に、あなたは、動的な関数名を生成されていません。 – jxh

答えて

2

STRING_FUNCTION_PREFIXディレクティブはmain.cで定義されていますが、string.cでは定義されていません。したがって、string.cがコンパイルされると、置換は行われません。あなたがgcc -Eでstring.cをコンパイルすると、これの効果がわかります。

#define STRING_FUNCTION_PREFIX myをmain.cではなくstring.hの先頭に配置する必要があります。そうすれば、それを必要とする.cファイルはすべて定義され、すべての場所で一貫しています。

1

あなたがその場合は、あなたがどのような値STRING_FUNCTION_PREFIXべきを知っている人に含まれる必要があるヘッダファイルとしてstring.cの内容を扱うべきであるC.にテンプレートのエミュレーションを作成しようとしているように見えますさあ。 string.cの内容がヘッダーファイルの場合は、その名前を変更して、たとえばstring_template.hのように変更します。

次に、あなたのように実装されたファイルmystring.cを持つことができます。

#define STRING_FUNCTION_PREFIX my 
#include "string_template.h" 
関連する問題