2010-12-13 22 views
0

私は定数の文字列が定義されている構造体と、自分の文字列オブジェクトへのポインタを持っています。目的は、charsとtxtをNULLに設定してこの構造体の変数を宣言し、実行時にcharを表すMyStringオブジェクトを作成することです。 GLibを使用している間は、コンパイル時にMyStringを作成できません。このライブラリでは、最初にg_type_initを呼び出す必要があります。mingw const char stringは確かにconstではありません

struct _MyStaticString { 
    volatile MyString * txt; 
    const char *chars; 
}; 

宣言は、次にようになりますので、新しいのMyStringオブジェクトを作成した場合、その後のtxtがNULLである場合には、第1の検査で私のMyStringオブジェクトを提供するためのrepsonsibleある機能が彼らのです

struct _MyStaticString my_test_string = { NULL, "Hello world or foo bar, or a rick roll" }; 

このMyStringオブジェクトを返します。

struct _MyString *my_static_string(struct _MyStaticString *a_static) { 
    printf("a_static=%lx\n", (gulong) a_static); 
    printf("a_static.chars=%s\n", (char *) a_static->chars); 
    if (a_static->txt == NULL) { 
     CatString *result = g_object_new(MY_TYPE_STRING, NULL); 
//  result->data = (gchar *) a_static->chars; 
     result->data = strdup((char *) a_static->chars); 
     result->size = strlen((char *) a_static->chars); 
     result->hash = 0; 
     g_object_ref_sink(G_OBJECT(result)); 
    result->parent.ref_count = 1000; 
    a_static->txt = result; 
} 
return (struct _MyString *) (a_static->txt); 

}

このすべてが素晴らしい作品と私​​はLinux上でGCCを実行しているとき、少なくとも私は、とても幸せです。私がMinGWコンパイラの助けを借りてWindows上でこのコードをコンパイルし始めると、間違ったことが起こり始める。私がすべてのプロジェクトを一つのプロジェクトに入れたら、それでもまだ良いですが、宣言を.aライブラリに入れて、それを他の場所で使うとすぐに、a_static-> charsはNULLになります。だから、私は演奏/微調整/テストを始めました。オブジェクトファイル内のデータが整列し、#pragma pack(16)が追加された可能性があります。それはうまくいかなかった。おそらく私を助けることができる属性があると思いました。だから私は__attribute__((共通))を追加しました。それはうまくいかなかった。私はスマートであると考えと構造体宣言から文字列を分離自体が好き:

const char helper_txt = "Hello world or foo bar, or a rick roll"; 
struct _MyStaticString my_test_string = { NULL, helper_txt }; 

を私はコンパイルエラーを取得:ここ

error: initializer element is not constant 
error: (near initialization for 'field.chars') 

は私のコンパイラフラグは

C:\MinGW\bin\gcc.exe 
    -IC:\MinGW\include 
    -IC:\GTK_ALL_IN_ONE\include\gtk-2.0 
    -IC:\GTK_ALL_IN_ONE\lib\gtk-2.0\include 
    -IC:\GTK_ALL_IN_ONE\include\atk-1.0 
    -IC:\GTK_ALL_IN_ONE\include\cairo 
    -IC:\GTK_ALL_IN_ONE\include\gdk-pixbuf-2.0 
    -IC:\GTK_ALL_IN_ONE\include\pango-1.0 
    -IC:\GTK_ALL_IN_ONE\include\glib-2.0 
    -IC:\GTK_ALL_IN_ONE\lib\glib-2.0\include 
    -IC:\GTK_ALL_IN_ONE\include 
    -IC:\GTK_ALL_IN_ONE\include\freetype2 
    -IC:\GTK_ALL_IN_ONE\include\libpng14 
    -IC:\work\workspace\module-blah\src 
    -O0 -g3 -Wall -c -fmessage-length=0 -mms-bitfields -DOSWINDOWS 

、ここでされていますバージョン

C:\>c:\MinGW\bin\gcc.exe --version 
gcc.exe (GCC) 4.5.0 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

コンパイラのフラグが足りないか、const char *の文字列を.a libにエクスポートするための属性を追加する必要がありますか?その文字列が.a libの天気をチェックする簡単な方法ですか?それとも、リンカのオプションがありますか?

+1

あなたは予約済みの識別子を使用している:大文字が続くアンダースコアで始まり、Cのいずれかの識別子は、(標準の7.1.3を参照)を実装用に予約されており、したがって、このプログラムは、未定義の振る舞いを呼び出しています。私のルールでは、識別子をアンダースコアで始めることは決してありません。 –

+0

また、「a_static-> charsフィールドがNULLになる」とはどういう意味ですか?特に何が起こったのですか?それは 'const char helper_txt'か正しい' const char * helper_txt'ですか? –

答えて

3

私の推測では、ライブラリ(.aファイル)以外のどこかであなたのプロジェクトのNULL値に変化している変数の宣言のように見えます。 GCCとリンカは、複数の.cファイル(または複数の.cファイルに含まれる.hファイル)で同じ変数を宣言するようなことをすると、厳密なCの文字ではなく、あなたの意図に従うようなコードを生成することがあります同じプロジェクトの.cファイル)。これが何をもたらすべきかは変数の複数のコピーであり、おそらくあなたのコードに同じ名前の複数のオブジェクトがあることを示すリンカエラーですが、何らかの理由で一緒にリンクしているときに必ずしも起こるとは限りません同じ変数の重複を含む多くの.oファイル

私の推測では、ここにあるものではなく:あなたが持っているヘッダファイル内

extern struct _MyStaticString a_string; 

struct _MyStaticString a_string; 

、あなたが本当の宣言考えるもの持っていたこと - 初期のものを - .cファイル内。あなたがライブラリに本当の宣言を移動するときa_stringオブジェクトの必要性を満たすとき

はリンカの動作が変更されました。メインプログラムの.oファイルから既に1つ以上のファイルがあるので、ライブラリを探すのは面倒ではありませんでした。これまでは、.oファイルからいくつかのファイルがあり、初期化されたファイルをゼロ以外の値またはNULL以外の値(グローバル変数または静的変数のデフォルト)にすることに決めました。しかし、初期化された変数のリンカーを使わないと、初期化されていないバージョンの変数の1つをライブラリに入れてから、使用したい値を探すことさえできます。

+0

これは非常に説得力のある説明のようです。解決策:すべてのヘッダファイルで変数が 'extern'と宣言されていることを確認してください。 – caf

+0

私はそれをテストしたし、動作するようです。 Yeeeeha ...私はそれについてGlühweinを飲むでしょう。私はexternのキーワードで遊んだが、私はちょうどそれを正しい場所に置いておらず、何の考えもしなかった。しかし、これはLinux上のgccとはまったく異なる動作です – LittleFunnyMan

関連する問題