2

私はプログラムを作成しています (まあ... Tektronix のサンプル コードを使用して) ラボのスペクトル アナライザへのネットワークを介したメッセージ交換をテストしています。

「decl-32.h」というヘッダー ファイルが提供されており、サンプル コードには次の行と、生成されるエラーが含まれています。

ibwrt(GpibDevice, "SYSTem:ERRor:ALL?", strlen("SYSTem:ERRor:ALL?"));

「'const void*' から 'PVOID {aka void*}' への無効な変換 [-fpermissive]」

ヘッダー ファイル内で、次のコード行がエラーとして強調表示され、次のエラーが表示されます。

extern int __stdcall ibwrt (int ud, PVOID buf, long cnt);

「'int ibwrt(int, PVOID, long int)' [-fpermissive] の引数 2 を初期化しています」

問題は、私がそのような複雑な変数の定義、使用、および変換に慣れていないことです。

どなたか親切にアドバイスをいただけないでしょうか。これは、そのような変数の型や変換などに慣れていない他の多くの人に関係があると確信しています.

前もって感謝します!

4

2 に答える 2

2

の 2 番目のパラメータibwrtPVOID、 の typedef ですvoid*。C++ では、ポインター型は暗黙的に に変換できますvoid*が、他のすべての型と同様に、変換で修飾子を削除することはできません。つまり、const char*(文字列リテラルが減衰する型) からへの変換void*は不正です。したがって、エラー。

コードの出所である C 言語では、文字列リテラルは崩壊しchar*、行はそのままコンパイルされます。constその理由は歴史的なものです - C の初期の実装にはキーワードがありませんでした。

それを修正するには、次のようにキャストしconstますconst_cast

const char* s = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, const_cast<char*>(s), strlen("SYSTem:ERRor:ALL?"));

渡したポインターを介して文字列リテラルを変更しようとしない関数を信頼する必要があります。そうしないと、未定義の動作が呼び出されます。この場合、安全な仮定のように思えます (そうではないかもしれませんが、パラメーターの名前はbufです、念のため!)、確認したい場合は、@MikeSeymour が彼の回答に示すように、文字列のコピーを作成してください。

于 2013-10-31T07:47:09.553 に答える
1

問題は、文字列リテラルが不変であり、この関数がconstデータへの非ポインターを必要とすることです。

関数がデータを変更しないことが保証されていて、欠落constが単なる見落としである場合は、必要な型にキャストできます。

ibwrt(GpibDevice, const_cast<char*>("SYSTem:ERRor:ALL?"), strlen("SYSTem:ERRor:ALL?"));

データが変更される可能性がある場合、未定義の動作が発生するため、文字列のローカル コピーが必要になります。

const char message[] = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, message, strlen(message));

(あまり目立たない長さを指定することもできますが、おそらくより効率的ですsizeof message - 1)

于 2013-10-31T07:42:07.497 に答える