0

私は午後中ずっとこれに固執しており、「関数を介して配列へのポインターを渡すc ++」という検索を試みても、有効な答えが見つからないので、ここに私の質問があります。

始める前に、これは OpenGL に関する質問ではなく、配列ポインタの受け渡しに関する質問です。

また、'....' (4 つのドット) と '...' (3 つのドット) を混同しないでください。'....' (4 つのドット) でスキップしているコードがたくさんあります。... (3 つのドット) は、関数に渡される可変数のパラメーターの楕円パラメーターです。

以下は、関連する 4 つのファイルの抜粋です。

OpenGL.h

class OpenGL {
.... (other unrelated stuff)

public:
    int * iPixelFormatAttribList[];    <----------

....

ユーティリティ.h

template <typename T> void LoadArray (T * [], int, ...);    <--------

ユーティリティ.cpp

// Dynamically Load Array.
template <typename T>
void LoadArray (T * Dest [], int count, ...) {   <-------
    va_list list;
    va_start(list,count);
    T * temp [] = new T [count];
    for (int cnt = 0; cnt < count; cnt++)
        * Dest[cnt] = va_arg(list, T);

    va_end(list);
    Dest = temp;
    delete [] temp;
}

OpenGL.cpp

void OpenGL::V3_SetupPixelFormat() {
.....

LoadArray (
   iPixelFormatAttribList,     15,          <---------
   WGL_DRAW_TO_WINDOW_ARB,     GL_TRUE,
   WGL_SUPPORT_OPENGL_ARB,     GL_TRUE,
   WGL_DOUBLE_BUFFER_ARB,      GL_TRUE,
   WGL_PIXEL_TYPE_ARB,         WGL_TYPE_RGBA_ARB,
   WGL_COLOR_BITS_ARB,         32,
   WGL_DEPTH_BITS_ARB,         24,
   WGL_STENCIL_BITS_ARB,       8,
   0
   // End of attributes list
 );

さて、ここで私がやろうとしていること。クラス定義 (OpenGL.h、OpenGL クラス) では、スペースがどのメンバーにも割り当てられていないことを知っています。また、それを作成するときに、配列に必要なパラメーターの数がわからないため、リストを動的に割り当ててセットアップする方法を見つけて、後で OpenGL 呼び出しに渡すことができるようにする必要があります。

(私がこのような動的ローディング リストを設定することにしたもう 1 つの理由は、このようにいくつかの配列が関係しており、配列をロードしているためです。また、後で同じタイプの機能が double やベクトル データ以外にも必要になる可能性があるためです。このユーティリティ テンプレートの作成前向きな考え方のようです。)

これはすべて問題ないように見えます。実際、コンパイルは正常に行われますが、リンクされません私は以下を取得します:

**** Internal Builder is used for build               ****
windres --use-temp-file -i..\res\resource.rc -o..\res\resource_rc.o
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\OpenGL.o ..\src\OpenGL.cpp
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\main.o ..\src\main.cpp
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\Utilities.o ..\src\Utilities.cpp
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\App.o ..\src\App.cpp
g++ -D_SS_DEBUG_ -ID:\Dev\Projects\Eclipse\OpenGL3\res -O0 -g3 -Wall -c -fmessage-length=0 -std=gnu++0x -o src\Win.o ..\src\Win.cpp
g++ -o OpenGL3.exe src\main.o src\Win.o src\Utilities.o src\OpenGL.o src\App.o ..\res\resource_rc.o -lopengl32 -lglew32 -lglu32 -lkernel32 -lgdi32 -lcomdlg32 -luser32
src\OpenGL.o: In function `ZN6OpenGL19V3_SetupPixelFormatEv':
D:\Dev\Projects\Eclipse\OpenGL3\Debug/../src/OpenGL.cpp:54: undefined reference to `void LoadArray<int>(int**, int, ...)'
collect2: ld returned 1 exit status
Build error occurred, build is stopped
Time consumed: 3000  ms.  

私にとって重要な行は次のようになります。

  undefined reference to `void LoadArray<int>(int**, int, ...)'

これが伝えているように見えるのは、関数を呼び出す方法です。

LoadArray (
    iPixelFormatAttribList,    15,
    WGL_DRAW_TO_WINDOW_ARB,    GL_TRUE,
    WGL_SUPPORT_OPENGL_ARB,    GL_TRUE,
    ....

そして、テンプレート関数を定義する方法:

 template <typename T> void LoadArray (T * [], int, ...);

と:

 template <typename T>
 void LoadArray (T * Dest [], int count, ...) {

一致しない。私はそれだけを得ます。

私が得られないのは、テンプレート(または呼び出し)を調整して、リンクできるようにする方法です(つまり、関数シグネチャがすべて台無しになりました)。

これの基本的な考え方は、配列ポインター、要素数、および要素のリストを指定して LoadArray を呼び出し、配列要素を含む新しいリストを指すようにポインターを変更することです。

これを行うための派手な C++ の方法があると確信していますが、ここでそうあるべきだと思われるように、これを機能させる方法を理解したいと思います。(つまり、ここで何が間違っていたのかを正確に知っていれば、私が間違っていたことを教えてくれないリダイレクトソリューションではなく、学ぶのに役立ちます。このような配列ポインタ、私はそれを正しくするための正しい黒魔術を理解することができません.)

ありがとう。

4

2 に答える 2

0

Move your all your template code to the header file. That makes straight forward for the compiler to instantiate instances of your template class for different template parameters. If you don't do this then you need to force instantiation of the template for the types you need.

于 2012-05-04T07:55:02.320 に答える
0

テンプレートを次のように定義してみませんか

template <typename T>
void LoadArray(T **Dest, int count, ...) {

そして、それで終わりですか?

于 2012-05-04T07:49:31.383 に答える