私は次のコードを持っています:
HANDLE h = NULL;
init(h);
dosomething(h);
dosomething関数で使用するためにinit関数に「h」を設定するにはどうすればよいですか?
Cが値を渡すときに、のアドレスh
をに渡す必要があります。init()
void init(HANDLE* a_h)
{
*a_h = ...; /* some handle. */
}
呼び出されます:
init(&h);
if (h)
{
dosomething(h);
CloseHandle(h);
}
のアドレスをに渡すことに加えて、のHANDLE
取得init()
に失敗した場合に必要なアクションに応じて、この情報を呼び出し元に提供できない場合に最後のエラーを格納するためHANDLE
にのアドレスを渡すこともできます。DWORD
void init(HANDLE* a_h, DWORD* a_last_error)
{
*a_h = /* code to acquire handle. */;
if (NULL == *a_h) *a_last_error = GetLastError();
}
多くの人が示唆しているようにアドレスを渡すことに加えて、代わりに関数からハンドルを返すことをお勧めします。それはややクリーンなコードになります:
HANDLE h = init();
ハンドル自体ではなく、ハンドルのアドレスを渡す必要があります。参照による呼び出しと値による呼び出しを確認します。現在、値で呼び出しているため、によって行われた変更init()
はローカルのみです。
あなたが欲しいものは次のようなものです:
void init(HANDLE *h)
{
*h = something;
}
....
...
HANDLE H=NULL;
init(&h);
init(&h)
代わりに電話するinit(h)
そして、次のように定義init
します
void init(HANDLE * h)
{ /* do whatever */ }
その後、変更はメインにも表示されます。
HANDLE
また、小さな注意:のポインタ/アドレスもに渡す必要があるかもしれませdosomething()
ん(そこで何を達成したいかによって異なります)
以前の回答について詳しく説明します。データの非表示を使用するには、ハンドルを実装の外部のvoidポインターとして定義し、内部の実際の構造を定義する必要があります。これにより、実装のみが構造の構成を確認できます。
ヘッダーファイル:
typedef void * HANDLE;
void init(HANDLE *h);
void dosomething(HANDLE h);
void destroy(HANDLE *h);
実装:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int contents;
} * HANDLE;
void init(HANDLE *h) {
*h = (HANDLE)malloc(sizeof *h);
(*h)->contents = 2;
}
void dosomething(HANDLE h) {
printf("Contents are: %d\n", h->contents);
}
void destroy(HANDLE *h) {
free(*h);
*h = NULL;
}
そして、呼び出し元の関数:
HANDLE h = NULL;
init(&h);
dosomething(h);
destroy(&h);
ヘッダーファイルをインクルードすることを忘れないでください。