本ページは公開が終了した情報の複製であり、掲載時点での情報です。本ページに記載されている内容について各所に問い合わせることはご遠慮下さい。
C/C++
インストール/環境設定
統合環境
ツール
プログラミング
プログラミング:DOS
プログラミング:DPMI
プログラミング:Windows
プログラミング:OWL
ライブラリ:OWL
ドキュメント
一般的な質問と回答
FIWRQQ 等のシンボルが見つからないエラーが発生します
FIWRQQ 等のシンボルが見つからないエラーが発生するのですが?
FIxxx ( FIRWQQ FIDRQQ ) 関数は浮動小数点のサポートライブラリです。 TLINK に渡すライブラリの順番が不当ですとこのようなエラーが発生します。 ライブラリの順番に注意して渡すようにしてください。
TLINK C0x.OBJ user.obj,EXE,MAP,[GRAPHICS.LIB] [EMU.LIB|FP87.LIB] Cx.LIB
.EXE のサイズが大きくなってしまう
(Borland/Turbo)C++ 4.x を使用して .EXE のサイズを小さくしたいのですが。
Turbo/Borland C++ 4.x では例外処理をサポートしたために例外処理の初期化コード をデフォルトでリンクしてしまいます。 また,CONIO.H に含まれる関数の PC98 や DOS/V での機種依存性を吸収したために若干ライブラリが大きくなっています。
.EXE のサイズは次のようにして小さくすることが可能です。
例外処理を使用されていないプログラムの場合には(ObjectWindow 2.x やクラス ライブラリは例外処理を使用しています)NOEHx.LIB または NOEHWx.LIB をリンク します。 NOEHx.LIB は DOS アプリケーションに,NOEHWx.LIB は Windows アプリ ケーションに対して使用します。 またはそれぞれのメモリモデルを示します。
CONIO.H を使用していて PC98 シリーズまたは,DOS/V に依存したプログラムを 作成する場合には CONIONEC.LIB または CONIOIBM.LIB をリンクします。
CONIONEC.LIB は PC98 シリーズ用,CONIOIBM.LIB は DOS/V 用のライブラリです。
浮動小数点を使用していて PC98 シリーズまたは,DOS/V に依存したプログラムを 作成する場合で,エミュレーションを行なっている場合にはそれぞれ EMUNEC.OBJ EMUIBM.OBJ をリンクし,子プロセッサを使用するプログラムを作成している場合 にはそれぞれ FP87NEC.OBJ FP87IBM.OBJ をリンクしてください。
オーバレイを使用していて PC98 シリーズまたは,DOS/V に依存したプログラムを 作成する場合には OVLYNEC.LIB または OVLYIBM.LIB をリンクしてください。
OVLYNEC.LIB は PC98 シリーズ用,OVLYIBM.LIB は DOS/V 用のライブラリです。
CLOCK.C が登録できないのですが?
CLOCK.C を登録すると Invalid Filename のエラーが発生します。
PC98 では CLOCK というファイルを扱うことは許されません。 CLOCK はデバイス名として使用済みのファイルです。ファイル名を変更してご利用ください。 CON や AUX 等も,DOS/V では COM1 等も同様にご利用頂けません。
引数リストが多いというエラーが発生します
引数リストが多いというエラーが発生します。
コマンドラインコンパイラやリンカはレスポンスファイルを指定することができるようになっています。 レスポンスファイルはコマンドラインの引数リストをテキストファイルに記述したものです。 引数リストが多い場合にはレスポンスファイルを記述しプログラムに渡してください。
tlink @test.rsp
レスポンスファイルの記述方法はプログラムによって改行に使用されるコードが異なりますのでそれぞれのガイドを参照してください。
DPMI server initialization error -> v86 task without vcpi
プロテクトモードのツールを起動する際に次のエラーメッセージが出る場合にはどうしたらよいですか? DPMI server initialization error -> v86 task without vcpi
既に使用されている仮想86ドライバが VCPI 及び DPMI のどちらの規格にも対応していないことを意味します。 対応したドライバを使用するか,現在使用しているドライバを外して使用してください。
3.1 以前のコンパイラを使用していて,NEC MS-DOS 5.0A に付属の EMM386.EXE を組み込んでいる場合には DOS に付属の DPMI.EXE を常駐することで動作します。
4.0 以降では DPMI.EXE では使用可能なプロテクトメモリが 2M に制限されているために使用できません。
NEC MS-DOS 6.2 を使用している場合には EMM386.EXE を組み込む際に /DPMI のオプションを指定してください。
Borland C++ が起動できない
Turbo C++ for Windows や Borland C++ に付属する Windows IDE(統合環境) やResource Workshop を起動すると DOS に戻ってしまったり,そのままプログラムマネージャに戻ったり,EMM386 などとの GP が発生するなどで,起動できません。
インストールされている BWCC.DLL が古いかまたは英語版の BWCC.DLL がインストールされている可能性が考えられます。 BWCC.DLL は統合環境も使用しているBorland Windows Custom Control で再配布可能なファイルであるため Borland の製品以外にも添付され,あらゆるディレクトリにインストールされていることが考えられます。そこで Windows のディレクトリに限らず,全てのドライブに渡ってBWCC.DLL を検索し,見つかった場合には統合環境(BCW.EXE や TCW.EXE)のタイムスタンプと見比べ一致しない場合には削除するかリネームしてください。もし一致するファイルが存在しなかった場合にはマスターディスクから(FD であれば一枚目にある FILELIST を参照すればどのファイルに圧縮されているか確認できます。
CDROM であれば INSTALL ディレクトリにある)圧縮ファイルを展開し,Windows のSYSTEM ディレクトリに置くようにしてください。
また一部の Windows では最低解像度以外で起動できない場合があります。この場合には Windows の修正バージョンアップ(ビデオドライバ等)を行なう事をお勧め致します。
注意:BWCC.DLL はそれぞれのコンパイラに付属する物をご使用ください。
2バイトコードのディレクトリ名やファイル名
2バイトコードを使用できますか?
統合環境やコンパイラは2バイトコードを含むディレクトリ名やファイル名には対応しておりません。 2バイトコードを含む名前の使用を避けるようにしてください。
IDE のデバッカーでローカル変数を評価することができません
IDE のデバッカーでローカル変数を評価することができません。
ローカル変数は,その変数のスコープ内でしか評価する事はできません。
スコープ内で評価できない場合は,デフォルト・オプティマイズによる影響と思われます。volatile 予約語を使って,変数を定義してお試し下さい。
DPMI プログラムのリモートデバッグは可能ですか?
DPMI プログラムのリモートデバッグは可能ですか?
残念ながら DPMI16/32 のリモートデバッグはサポートされておりません。
TIArrayAsVector と .DLL
DLL でインスタンスが生成されそのメンバを呼び出すような場合,そのインスタンスはエクスポートされませんのでエラーが発生します。 BIDS のメンバを .DLL で閉じた形で使用するようにしてください。 具体的には,ポインタや参照で定義しコンストラクタで初期化するようにしてください。
class _DLLCLASS TTest {
public:
TValAry *pValAry;
:
TTest::TTest(void) : pValAry( new TValAry(10) )
{
:
IME の制御はどうすればできますか?
IME の制御はどうすればできますか?
Windows 3.1でのIME の制御は SendIMEMessage を使用して行ないます。指定するデータを確保し(IMESTRUCT),fnc に対して制御に関するデータをセットします。
(IME_SETOPEN 等)詳しくは Windows IME に関するヘルプを参照してください。
Turbo/Borland C++ で作成した .obj ファイルと Delphi をリンクするには?
Borland C++5.0J と Turbo C++5.0Jで作成した .obj ファイルとDelphi の {$L} でリンクするには,どのように記述すればいいですか?
以下の様に記述して下さい。
ただし,リンクするオブジェクトは外部のサポート関数などを呼び出していてはいけません。
// TESTC.C
int pascal _export testfunc( int i );
// TESTPAS.PAS
.
.
implementation
{$R *.DFM}
{$L TESTC.OBJ}
function testfunc( i: Integer ): Integer; stdcall; external 'TESTC.OBJ';
.
.
以下関数 TESTFUNC は参照できる様になります。
C++ で __finally キーワードを使う方法
該当するバージョン: Borland C++ 5.0, C++Builder 3.0, C++Builder 4,
C から C++までコードを扱う多くの開発者を混乱させる論点は,__finally キーワードです。try~__finally キーワードは,C コンパイラーを使うときだけ,利用することができます。__finally は C++で利用することができず,それは,ANSI C++の規格ではありません。
try ~ __finally の構文
// セットアップ・コード
try {
// プロジェクト・コード
}
__finally {
// __finally ブロック
}
C++に try~__finally を使う C コードを書くには,上記に示す構文で始めます。
そして,ローカルオブジェクト中のブロックのためのセットアップとクリーンアップ・コードを置きます。C++ は,例外が発生したとき,ブロックを抜け出し,ローカルオブジェクトが破棄されることを保証します。C コードと同等である C++を下記に示します:
class LocalObject {
LocalObject() {
// セットアップ・コード
}
~TLocalObject() {
// __finally コード
}
};
LocalObject local;
try {
// プロジェクト・コード
}
最後のステップは,-xd オプションを付けてコンパイルすることです。-xd を付けることで,すべてのオブジェクトが自動保管され,デストラクターが呼び出されます。
スタックは,例外が補足されるポイントへ例外を送出するポイントから進みません。
1000 以上の数をコンマ区切りで出力する方法
C++の IOStreams を使って,どのように 1,000,000のように,コンマでフォーマットされた数を出力するのでしょうか? C++ の IOStreams には,このためのサポートがまったくないのと同様にみえます。下記のサンプルコードの中の関数には,2つの処理(long 値を文字列に変換する処理と3桁ごとにコンマを挿入する処理)が提供されています。変換中にコンマを加えることは,sprintf()を使って long 値を文字列に変換し,修正するよりずっと容易です。
このコードは,初級プログラマーにとって,文字列をリバースするオペレーターの使い方を示す優れたサンプルです。リバース・アルゴリズムは,標準テンポラリー・ライブラリ中の reverse()関数と同等です。
#include <iostream.h>
const char *commaStr(unsigned long number)
{
const int size = 15; // 最大値桁数
static char str[size]; // 戻り値の文字列
char *ptr1, *ptr2; // ホルダーの場所
char tempStr[size]; // ワークエリア
int counter = 0; // 3桁のカウンタ
ptr1 = tempStr;
do {
// 最右の数字を捕らえ,0 キャラクターを加えます
*ptr1++ = (char)(number % 10) + '0';
// 最右の数字を取り除きます
number /= 10;
// 3桁移動したら,文字列にコンマを挿入します
if (number && !(++counter % 3))
*ptr1++ = ',';
// ゼロになるまで繰り返します
} while(number);
// このループは文字列のキャラクタをリバースします
for( --ptr1, ptr2 = str; ptr1 >= tempStr; --ptr1)
*ptr2++ = *ptr1;
// 文字列の終末にヌル文字を付けます
*ptr2 = '\0';
return str;
}
// 簡単なテスト関数
int main() {
cout << commaStr(154056L) << endl;
return 0;
}
これは便利なコードの断片です。このサンプルをデバッガを使って,コードの中を追い,どのようにして動作するか監視して試てはどうでしょう。どのようにモジュールが動作するかを見るために,デバッグ|評価|変更コマンドを使います。そして,このタスクがどのように完了するか理解するために,リバース・コード中のポインタをインスペクして試てください。
割り込みハンドラにおける注意点は?
割り込みハンドラにおける注意点は?
一般に,タイマー割り込みを扱う関数(割り込みハンドラ)には次のような制約があります。
MS-DOS のシステムコールを発行してはいけません。MS-DOS のシステムコールはリエントラント(再入可能)でないため,システムコールの処理中に割り込みがかかり,割り込みハンドラからさらにシステムコールを呼び出すことになると正常な処理を継続できないためです。
BIOS の使用はできるだけ避けてください。原則としては,BIOS もリエントラントではないためMS-DOSのシステムコールと同様,割り込みによって正常な処理を継続できないことがあります。たとえば,クロック BIOS の処理中に割り込みハンドラからさらにクロック BIOS を呼び出すとクロック LSI がテストモードに入ってしまい,正常な時間が取得できなくなることがあります(この場合は,時刻を再度設定し直してください)。BIOS によっては処理に時間が掛かりすぎて割り込みハンドラとして不適切なものもあります。
setjmp, longjmpは使用できません。割り込みハンドラは,必ず呼び出し元に返るようにしてください。
スタック消費量に注意してください。割り込みハンドラが呼び出されるときに使われるスタックは,プログラムが確保したスタックではない場合があります。常駐プログラムや MS-DOS の処理中は,独自のスタックが使われていることがありますから割り込みハンドラがスタックを大量に消費するとプログラム自身がどれだけ多くのスタックを確保していても正常な処理が行なえないことがあります。
スタックチェックをはずしてください。スタックチェックは,自分自身が確保したスタックの大きさを調べるだけです。4.で述べたように別のプログラムのスタックが使われる場合は,スタックチェックは意味がありません。誤って,スタックのオーバーフローが発生した場合は割り込みハンドラから復帰できないためにハングアップしてしまうことも考えられます。なお,Turbo C++ や Borland C++ では interrupt 修飾子が使われた関数は自動的にスタックチェックがはずされます。しかし,割り込みハンドラから呼び出される関数にスタックチェックコードが含まれている場合は,同じ問題を引き起こすことがあります。
浮動小数計算をしないでください。メインプログラムで数値計算をしている場合,計算中に割り込みがかかると,コプロセッサの状態が割り込みハンドラによって変更されてしまうことになります。この場合,割り込みハンドラから復帰しても以前の状態に復帰できません。少なくとも,コプロセッサでは,FSAVE/FRSTOR 命令でコプロセッサの状態を退避/復帰する必要があります。また,エミュレータはリエントラントではないため,割り込みハンドラから利用することはできま せん。
スモールデータモデルでは,割り込みハンドラ内では DS != SS となることに注意してください。割り込みハンドラが呼び出されるときは,データセグメントはプログラムのデータセグメントが割り当てられますが,デフォルトではスタックセグメントは呼び出し側のままになります。sprintf など多くのライブラリ関数が DS == SS であることを前提に動作しますので,データセグメント内にローカルスタックを割り当てなければ,これらのライブラリ関数正しい動作をしません。
プログラムがリダイレクトされているときのコンソール入力について
プログラムがリダイレクトされているときのコンソール入力について。
プログラムがリダイレクトされているときに,getch などのライブラリ関数でコンソールからの入力を受け付けるようにするには,リダイレクトされているファイルハンドルを別のファイルハンドルに割り当て直し,ファイルハンドルの0をコンソール入力に割り当て直す必要があります。プログラム例は,次のとおりです。
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <conio.h>
main()
{
char buf[BUFSIZ];
int handle, handle2, handle3;
int lines;
FILE *fp;
handle = fileno(stdin); // handle は標準入力のファイルハンドル(0)
handle2 = dup(handle); // 標準入力を二重化
handle3 = _open("CON", O_RDONLY); // コンソール入力をオープン
dup2(handle3, handle); // ファイルハンドル0にコンソール入力を連結
fp = fdopen(handle2, "r"); // もとの標準入力をファイルストリームに
lines = 0;
while (fgets(buf, sizeof buf, fp)) {// リダイレクト先からの入力を
fputs(buf, stdout); // 標準出力へ
if (++lines > 23) {
lines = 0;
fputs("More...\n", stdout);
while (kbhit()) getch(); // キーバッファのクリア
getch(); // コンソール入力待ち
}
}
return 0;
}
BLACK 色の描画ができないようですが?
BLACK 色の描画ができないようですが。
serbkcolor 関数のリファレンスに次のように記述されています。
----- 抜 粋 -----
PC-9800 シリーズおよび DOS/V の CGA と EGA の場合,setbkcolor は,パレット番号の最初の項目を変更して,バックグラウンド色を変更します。したがって,setbkcolor で黒以外の色を指定した場合は,黒で描画したすべての内容がここで設定した色になります。
このため,setcolor(BLACK), setfillstyle(xxx, BLACK) 等の描画は,バックグラウンド色と同色となり,表示されていないように見えます。
オーバレイのプログラムをリンクすると No stub fixup ... が発生しますが?
オーバレイのプログラムをリンクすると No stub fixup ... が発生してしまいます。
オーバレイのプログラムをコンパイルする際には注意が必要です。仮想テーブルを持つクラスがある場合には -Vs(C++ Virtual table Local) を指定しなければなりません。Borland C++ 4.0 ではこれだけでよいのですが,Borland C++ 3.1 以前の製品については -B(Compile via Assembler) も指定する必要があります。
また Borland C++ 4.0 や Turbo C++ 4.0 以降の製品では例外処理や RTTI がサポートされています。オーバレイのプログラムを作成する際には RTTI は共存することが出来ませんので,RTTI は使用しないようにしてください。
仮想テーブルを持つクラスの代表は Turbo Vision ライブラリです。
C++ で書かれたコードから C で書かれた DLL をコールできますか?
C++ のコードから C で書かれたDLL をコールする方法を教えてください。
通常の関数を C++ から呼び出すのと同じように extern "C" で関数を修飾します。また,.DLL 側の関数は _export でエクスポートされていなければなりません。.DLL からインポートライブラリを生成するには IMPLIB.EXE を使用します。IMPLIB.EXE(IMPDEF.EXE)は正常な DLL であれば問題なく目的のファイルを生成出来ます。
SetDlgItemText で "\n" を渡しても改行されないのですが?
SetDlgItemText で "\n" を渡しても改行されないのですが?
エディットコントロールで改行コードを送る場合には "\r\n" を指定しなければなりません。"\n" を "\r\n" に変更してください。
OWL の 内部を TRACE する方法は?
OWL の 内部を TRACE するにはどうしますか?
OWL の内部を TRACEするには診断機能付きのライブラリを使用します。
診断機能付きのライブラリはインストール時には展開されませんので,ライブラリを再構築するか,CDROMからコピーしてください。
(CDROMの展開イメージに診断機能付きのライブラリーがありますのでハードディスクに余裕があれば lib ディレクトリを移動して下さい。)
さらにTargetExpert で「診断機能付きを使う」をにチェックしてください。
また,診断ツールとして\BC4x\EXAMPLES\OWL\OWLAPPS\DIAGXPRT\DIAGXPRT.IDEが用意されています。
NOEHxx.LIB とは何でしょうか?
NOEHxx.LIB はどのようなライブラリですか?
BC4.x, TC4.0 では例外処理をサポートしました。 その初期化ルーチンをデフォルトでリンクするために実行モジュールが大きくなってしまいます。 そこで,例外処理を使用しないアプリケーションのサイズを小さくするために用意されたライブラリがこの NOEHxx.LIB です。 'NOEH' の後に 'W' がつく物は Windows 用のライブラリで後の x (s, c, m, l, h) はそれぞれのメモリモデル用のライブラリを指します。
このライブラリを使用する場合には例外処理を使用するオプションを外し(-x-),それぞれのプラットフォーム,メモリモデルにあったライブラリを明示的に指定してください。
例えば次のように指定します。
BCC -x- TEST.C NOEHS.LIB (Borland C++ の場合)
TCC -x- TEST.C NOEHS.LIB (Turbo C++ の場合)
また,これらの記述は README にもございます。
動的に2次元配列を割り当てることができますか?
動的に2次元配列を割り当てることができますか?
以下に示すように,C または C++ では malloc() が使用でき,C++ では new 演算子が使用できます。
malloc(): 2 × 3 文字の配列を作成
int i;
char** p;
p = (char **) malloc(2 * sizeof(char *));
for (i=0; i<2; i++) p[i] = (char *) malloc(3);
new:
int j;
char** q;
q = new char* [2];
for (j=0; j<2; j++) q[j] = new char [3];
1つのモジュール内で 64KB を超える配列を静的に割り当てることは?
1つのモジュール内で 64KB を超える配列を静的に割り当てることができますか?
TC4.0 や BC4.x では,far データ変数がサポートされています。 変数を次のように定義してください。
64KB 未満のデータを複数宣言する場合:
...
char far array1[60000L];
char far array2[60000L];
...
64KB を超える配列の場合:
char huge array3[100000L];
cprintf で,'\n' を出力してもカーソルが行の先頭に移動しない
cprintf で,'\n' を出力してもカーソルが行の先頭 (左端) に移動しません。
同じ桁で1行下に移動するだけです。
cprintf は,'\n' を改行としてのみ解釈します。 カーソルを行の先頭に移動させるには,明示的に復帰コード (\r) を出力するようにします。
cprintf("\n\r");
プログラムでプリンタに出力するには?
プログラムでプリンタに出力するにはどうすればよいでしょうか?
STDIO.H で定義されている FILE ポインタ (stdprn) を使います。 stdprn は,使用前に開く必要はありません。
#include <stdio.h>
void main(void)
{
fprintf(stdprn, "Hello, printer!\r\n");
}
プリンタが行バッファ形式のときは,"\r\n" が送られたときに,一度に出力されます。 DOS によっては,CONFIG.SYS 中に PRINT.SYS などのプリンタドライバを組み込んでおく必要があります。
バイナリファイルを読み書き時の, (0x0d) や (0x0a) 文字の変更を防止
バイナリファイルを読み書きします。プログラムが復帰 (0x0d) や改行 (0x0a) 文字を変換してしまいます。 どうすればよいのでしょう。
テキストモードで開かれたファイルは,DOS のためにこれらの文字を変換します。
バイナリファイルでファイルを読むためには,バイナリモードでファイルを開きます。
#include <stdio.h>
int main(void)
{
FILE *binary_fp;
char buffer[100];
binary_fp = fopen("MYFILE.BIN", "rb");
fread(buffer, sizeof(char), 100, binary_fp);
:
}
デフォルトのファイルモードはテキストモードです。
textcolor で色を指定しても, printf や puts の文字の色が変わらない
textcolor で色を指定しても,printf や puts で表示される文字の色が変わらないのはなぜですか?
textcolor で指定される色は,cprintf や cputs などのコンソール入出力関数にのみ有効です。
#include <conio.h>
int main(void)
{
textcolor(BLUE);
cprintf("I'm blue.");
}
long 型の整数を表示するには?
long 型の整数を表示するにはどうすればよいでしょうか?
%ld 書式を使ってください。
long int l = 70000L;
printf("%ld", l);
サンプルプログラムが動作しません
サンプルプログラムの1つを読み込んで実行しましたが動作しません。 何が起きているのでしょうか?
この動作の最も一般的な原因は,.C または .CPP のサンプルファイルの読み込みで,プログラムを正しく構築し実行するためにプログラムに必要なすべてのものを含んでいないことです。 サンプルプログラムを構築する最良の方法は,それに プロジェクトファイル(.IDE あるいは .PRJ)や MAKEFILE が用意されている場合には,それを使用することです。
サンプルプログラムの利用方法
IDE からサンプルプログラムをコンパイルしリンクするにはどのようにするのですか?
[プロジェクト(P)|プロジェクトを開く(O)]を使って,実行したいプログラムに関連付けられているプロジェクトファイル (*.IDE) を開きます。[コンパイル(C)]や[再構築(B)]を使ってそのプロジェクトを構築し,[デバッグ(D)|実行(R)]を使ってそのプログラム出力を表示します。 IDE の使用法についての詳細は,『Borland C++ ユーザーズガイド』を参照してください。
MAKE で構築内容を変更するには?
MAKE の使用時にプログラムをどのように構築するかを変更するにはどのようにすればよいのですか?
処理するサンプルプログラムのディレクトリ内の MAKEFILE には,それをどのように構築するかを制御するために MAKE.EXE にどんなパラメータを引き渡すことができるかがこのファイルの先頭に指定されていることが多くあります。 たとえば,MAKE DEBUG=1 を使用すると,プログラムを進めながらデバッグ情報を含む,といったことなどが分かるはずです。
BGI Error: graphics not initialized (use 'initgraph')
どうして次のようなメッセージが表示されるのでしょうか?
BGI Error: graphics not initialized (use 'initgraph')
プログラムはグラフィック関数を使っていますが,initgraph は呼び出しています。
initgraph は,さまざまな理由で失敗することがあります。 失敗した理由は,graphresult が返す値を使って調べることができます。
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
int main(void)
{
int gerr; /* グラフィックスエラー */
int gdriver = DETECT, gmode;
// 自動検出を使ってグラフィックスを初期化し, .BGI ファイルと
// .CHR ファイルを C:\xC4x\BGI から探す
initgraph(&gdriver, &gmode, "C:\\xC4x\\BGI");
if ((gerr = graphresult()) != grOk)
{
printf("Error : %s\n", grapherrormsg(gerr));
exit(1);
}
:
}
グラフィックス関数を使っていて,BGI Error:graphics not initialized (use 'initgraph') が表示される主な理由には,カレントドライブに BGI ファイル(PC98.BGI や DOSVGA.BGI) が存在しない,統合環境から実行していてメモリが不足しているなどがあげられます。
すべての数学計算のライブラリ関数が誤った結果を返す
どうして cos() や tan() のような,すべての数学計算のライブラリ関数から誤った結果が生じるのでしょうか?
標準数学計算関数を使う前に,#include <math.h> を記述しなければなりません。
一般に C++ では,宣言されていない関数は int を返すものとしています。 数学計算関数の場合,通常は double を返します。 たとえば,次の例があげられます。
/* 誤り */
int main(void)
{
printf("%f", cos(0));
}
/* 正しい */
#include <math.h>
int main(void)
{
printf("%f", cos(0));
}
浮動小数点のエラーを“つかまえる”には?
浮動小数点のエラーを“つかまえる”にはどのようにしたらよいでしょうか?
『Borland C++/Turbo C++ ライブラリリファレンスガイド』の関数 signal やmatherr の項目を参照してください。 関数 signal は,80x87 や 80x87 エミュレータでのエラーをとらえるために使われます。 関数 matherr は,MATHx.LIB の関数で発生するエラーをとらえます。
C の関数と C++ の関数のリンク時に未定義エラーが発生
C の関数と C++ の関数をリンクしようとしています。リンカはすべての C の関数は未定義だというエラーを発生します。 なぜですか?
C++ のモジュールと C のモジュールをリンクするにはリンケージの指定が必要になります。C++ のモジュール内で,C 関数のプロトタイプは次の形式のうちいずれか1つを指定してください。
extern "C" declaration
extern "C" { declarations }
たとえば,C のモジュール内に次の2つの関数
"char *SCopy(char*, char*);" と "void ClearScreen(void)",
が存在する場合は,それらの関数は C++ モジュール内で次の形式のどちらかで宣言 される必要があります。
extern "C" char *SCopy(char*, char*);
extern "C" void ClearScreen(void);
または,
extern "C" {
char *SCopy(char*, char*);
void ClearScreen(void);
}
これを行わないと,リンク時に Undefined symbol エラーが発生します。 詳しくは標準ヘッダーファイルを参照してください。 また,「C++ に関する一般的な質問」も参照してください。
Linker Error: Unable to open input file 'C0x.OBJ'
どうして次のようなメッセージが出るのでしょうか?
Linker Error: Unable to open input file 'C0x.OBJ'
リンカは BC/TC++ の起動ファイルおよびライブラリファイルを BC/TC++ ライブラリディレクトリの中で探します。 このパスは,
TC4.0 の場合
[Options(O:オプション)|Directories(D:ディレクトリ)...]
BC4.x の場合
[オプション(O)|プロジェクト(P)]の[ディレクトリ]
を選択して指定できます。INSTALL プログラムは,最初に,起動ファイルおよびライブラリファイルをコピーしたディレクトリにこのパスを設定します。
リンカが検索するメモリモデルをインストールしたかどうかも確認しなければなりません。 エラーメッセージ内の 'x' はメモリモデルに対応します。たとえば,'s' はスモールを示し,'l' はラージを示す,といった具合です。
Linker Error: Undefined symbol '_main' in module C0
どうして次のようなメッセージが出るのでしょうか?
Linker Error: Undefined symbol '_main' in module C0
C のプログラムは,必ず main() と呼ばれる関数を含んでいなければなりません。
これは,プログラムで最初に実行される関数です。 関数名はすべて小文字でなければなりません。 プログラムに main() がなければ,これを入れてください。 複数のソースファイルを扱っているときは,main() を含んだファイルは,プロジェクトにリストされるファイルの1つだけになければなりません。
下線文字 '_' は,すべての BC/TC++ の外部記号として識別子名の前に置かれることに注意してください。
すべてのグラフィックスライブラリルーチンが未定義エラー
なぜリンカは,すべてのグラフィックスライブラリルーチンが未定義であると表示するのでしょうか?
「統合環境」,「コマンドラインコンパイラ」および「グラフィックス」のセクションを参照しください。
「Fixup overflow」とはなんですか?
「Fixup overflow」とはなんですか?
『Borland/Turbo C++ ユーザーズガイド』にある TLINK のエラーメッセージの一覧を見てください。 このエラーは,異なるメモリモデルでコンパイルしたオブジェクトをリンクした場合などに発生します。
アセンブリで作成した関数を C にリンクしたいが,未定義エラーに?
アセンブリで作成した関数を Turbo C++ にリンクしようとすると,リンカがその関数は未定義であるとエラーメッセージを表示してしまいます。
関数名の前に下線文字 '_' を付加しているかどうか確認してください。
BC/TC++ から呼び出される関数の先頭には,'_' が付加されていなければなりません (Turbo Assembler の高級言語サポート機能を使えば,こうした手間が不要になります)。 また,アセンブルするときは大文字小文字を区別しなければなりません。
このために,/ML または /MX オプションをつけてアセンブルしてください。
(C ではなく) C++ としてコンパイルしている場合は,「C++ に関する一般的な質問」で extern "C" について説明している箇所をご覧ください。
BGI をリンク時,「Segment group exceeds 64K : _text」エラー発生
BGI をプログラムにリンクしようとしたら,「Segment group exceeds 64K : _text」というエラーが発生します。
BGIOBJ ユーティリティを使用している場合は,オブジェクトが置かれるデフォルトセグメントは _TEXT になります。 BGIOBJ に /f スイッチをつけて,生成されるオブジェクトを他のセグメントに置くことを試みてください。
グラフィックスシステムでオブジェクトを登録するために registerfarbgidriver 関数と registerfarbgifont 関数を使用する必要があります。 これらの関数の使い方については UTILS.TXT の BGIOBJ の説明をご覧ください。
printf: floating point formats not linked というエラーが発生
printf: floating point formats not linked というエラーが発生するのはどうしてでしょうか?
TLINK コマンドラインでのライブラリの順序が正しくないと思われます (TLINK の構文についてはユーザーズガイトを参照してください)。 たとえば,ラージメモリモデルおよび BGI ルーチンを使用している場合には,TLINK ラインは次のようになるはずです。
tlink /v c0l myobj,,,mylib graphics emu mathl cl
オブジェクトファイルまたはライブラリがカレントディレクトリにない場合には,完全パス名を指定しなければなりません。 この完全パス名の指定によって,コマンドラインが128文字を超えて越えてしまう場合が多くあります (レスポンスファイルを使用する必要があります。 これについては,『ユーザーズガイド』を参照してください ) 。
Error: <name> defined in module <a> is duplicated in module <b>
C++ のモードで共用変数を使おうとしてコンパイルオプションを指定しましたが,リンカエラーが発生してしまいました。
Error: <name> defined in module <a> is duplicated in module <b>
C++ のモードでは,明示的な COMDEF はサポートされていません。 静的変数を使うか,C に変更してください。
Paradox Engine を使用するには?
Paradox Engine を使用するにはどのようにするとよいのでしょうか?
オンラインドキュメントの COMPAT.TXT を参照してください。
プログラムの実行時に,「Floating point formats not linked」
浮動小数値を使ったプログラムを実行すると,「Floating point formats not linked」というエラーメッセージが表示されるのはなぜですか?
浮動小数点書式 (scanf() とその関連関数) は,.EXE ファイルのサイズを抑制するために,常にリンクされるわけではありません。 これらを強制的にリンクするにはソースコードのどこかに次の文を入れてください。
extern unsigned _floatconvert; #pragma extref _floatconvert
スタックの大きさは,どのように変更できますか?
スタックの大きさは,どのように変更できますか?
DOS プログラムでのスタックサイズは,実行時にグローバル変数 _stklen を参照することで決められます。 たとえば,スタックサイズを 10000 バイトにするには,プログラムの中に以下の行を入れてください。
extern unsigned _stklen = 10000;
デフォルトのスタックサイズは 4096 バイト (4KB) です。スタックサイズは,コンパクト,ラージ,ヒュージモデルの場合は 64Kバイト,それ以外は 65519 (0xFFEF) バイトまでです。
Windows プログラムでは,スタックのサイズはモジュール定義 (.DEF) ファイルの STACKSIZE ラインによって制御されます。 モジュール定義ファイルについての詳細は,『プログラマーズガイド』および『ユーザーズガイド』やオンラインヘルプを参照してください。
プログラムの実行中に「Stack overflow」
プログラムの実行中に「Stack overflow」のメッセージが出てしまいましたが?
コンパクト,ラージ,ヒュージモデルであれば,スタックサイズは,上記の方法で大きくすることができます。 それ以外の場合は,使用できるスタック領域を広げるために,near ヒープ領域を削るなどの方法があります。 スタックオーバーフローは大量なローカルデータや再帰関数によってよく起こるエラーですが,スタック領域の消費量を減らす方法はいくつかあります。
ローカル変数を static と宣言する (static キーワードの使用効果につ いては,『プログラマーズガイド』を参照してください)。
int main(void)
{
char x[5000];
:
}
-->
int main(void)
{
static char x[5000];
:
}
変数をローカルではなく,グローバルにする。
char x[5000]; //main() の前にグローバルに割り当てる
int main(void)
{
:
}
変数を far ヒープ領域に動的に割り当てる。
#include <alloc.h>
int main(void)
{
char far* x;
x = (char far*)farmalloc(5000); //動的な割り当て
// または,C++ では new 演算子を使ってもよい
// x = new char[5000];
:
}
プログラムが終了した後に「Null pointer assignment」
プログラムが終了した後に「Null pointer assignment」と表示されました。
これは何を意味しているのでしょう。
スモールデータモデルで開発した BC/TC++ プログラムは,DOS に戻る前にそのデータセグメントの先頭が不正でないかを確かめます。 このメッセージは,初期化をしていないポインタを使っていたり,プログラムが他の方法でメモリを不正に侵していることを警告するものです。 実体のないポインタや,範囲を超えて使われているポインタなど,ポインタの取り扱いに誤りがないかどうか確認してください。
dos.h に対して「Value of type void is not allowed」
該当するバージョン: Turbo C++ 4.0, Borland C++ 4.0, Borland C++ 4.5, Borland C++ 5.0
dos.h に対して「Value of type void is not allowed」が出ます。
BC/TC++ 特有のキーワードを使うときは,以下の設定をオフにする必要があります。
TC4.0 の場合
[Options(O:オプション)|Compiler(C:コンパイラ)|Source(S:ソースコード)...]の[ANSI]オプション
BC4.x の場合
[オプション(O)|プロジェクト(P)|コンパイラ|ソースコード]の[ANSI(A)]オプション
キーワードの一覧はそれぞれ,『Borland C++ プログラマーズガイド』,『Turbo C++ プログラマーズガイド』にあります。
malloc や calloc の動作が,メモリーモデルによって異なる
malloc や calloc を使って,メモリを動的に確保するプログラムをスモールデータモデル (タイニィ,スモール,ミディアム) でコンパイルすると正常に動作しますが,ラージデータモデル (コンパクト,ラージ,ヒュージ) でコンパイルしたら,ハングアップしてしまいました。
プログラム中に #include <stdlib.h> または #include <alloc.h> があることを確認してください。
far ポインタが,64KB を超えたときにオフセットだけ元に戻る
far ポインタを宣言しましたが,64KB を超えてインクリメントしたときにオフセットだけ元に戻ってしまいました。 64KB 以上のデータはどのように参照したらよいでしょうか?
huge ポインタを使ってください。 ヒュージモデルでコンパイルした場合も,デフォルトのポインタは far として扱われます。
TVision,CLASSLIB のコンテナクラスライブラリ使用時にリンカーエラー
Borland C++ のライブラリ (ObjectWindows,Turbo Vision,CLASSLIB ディレクトリのコンテナクラスライブラリ,あるいはランタイムライブラリ) の1つを使ったアプリケーションを構築しようとするとリンカエラーが出ます。 どうしたらよいでしょうか?
ライブラリ自体がコンパイルされたときには指定されなかった,リンクに関連するオプションが使われていると考えられます。 あるいは,問題のライブラリを変更する必要があるかもしれません。 以下のようなことが考えられます。
far 仮想テーブルを使って (-Vf または[オプション(O)|プロジェクト(P)|16 ビットコンパイラ|メモリモデル]の[FAR 仮想テーブル(F)]) iostream.h をインクルードして記述したファイルをコンパイルしている場合,同じオプションでiostream ライブラリを再構築しないとアプリケーションは正しく構築できません。
Turbo Vision アプリケーションをワードアラインメント (-a または[16ビットコンパイラ|プロセッサ|データの配置]の[Word(W)]) を使ってコンパイルする場合,同じオプションで Turbo Vision ライブラリを再構築しなければなりません。
コンテナクラスライブラリのテンプレート機能を使って ObjectWindows アプリケーションを構築する場合,クラスライブラリ (BIDxxxx.LIB ファイル) のテンプレート機能をソースから使って,必要な ObjectWindows ライブラリを再構築しなければなりません。
追加モードでファイルを開いても,付加したデータが見つかりません
追加モードでファイルを開いてファイルの最後にデータを付加することがあります。
しかし,付加したはずのデータをテキストエディタで確認しようとしても,そのデータが見つかりません。 どうしてでしょうか?
データは,EOF 記号の後に付加されています。 テキストエディタでは,EOF 記号の後のデータは表示できないものがあります。 EOF 記号を取り除くには,次のようにします。
filelength() 関数でファイル長を取得する。
FILE *file_pointer = fopen("file.nam","a");
long length = filelength(fileno(file_pointer));
chsize() 関数を使用してファイル長を現在の長さ -1 に変更する。
length to the current length-1:
chsize(fileno(file_pointer), (length -1));
次に付加したデータをファイルに書き込む。
coreleft() が正しい値を返さない
自分のプログラムを実行し,メモリを割り当て,coreleft() を使って使用可能なメモリの量をチェックしました。 その後,一部のメモリを解放して再度 coreleft() を呼び出しました。 すると,同じ値が戻されます。 なぜですか?
coreleft は使用可能なメモリの量を戻すものではありません。 割り当てられている一番上のブロックよりも上にある使用可能なメモリの合計を戻します。 これは,割り当てられている一番上のブロックよりも下にある「穴」の中の使用可能なメモリを戻すものではありません。
printf でファイルに出力した値が, scanf で読み込めない
printf でファイルに出力した値が,同じ書式を使っても scanf で読み込むことができません。
printf と scanf の書式は,似ていますが,完全に同一ではありません。 たとえば,printf では,float 型と double 型の値を,いずれも %f 指定で出力できますが,scanf では,float は %f,double は %lf と両者を区別しなければなりません。 また,出力するときにそれぞれの値をスペースで区切っておかなければ,正しく入力されないことがあります。
数値を,3桁ごとにカンマで区切って出力するには?
数値を,3桁ごとにカンマで区切って出力することはできますか?
標準ライブラリにはそうした関数は用意されていないので,専用の関数を作らなければなりません。 以下に long の値の場合を示します。
#include <stdio.h>
char *comma(long x)
{
static char buf[20];
int i, n;
long bs;
for (n = 0, bs = 1L; n < 9 && x/bs > 9; n++, bs *= 10L)
;
i = 0;
do {
buf[i++] = '0' + x/bs;
x -= (x/bs)*bs;
if (n%3 == 0) buf[i++] = ',';
bs /= 10L;
} while (n--);
buf[i-1] = 0;
return buf;
}
main()
{
printf("\\%s\n", comma(12345L));
}
※ここで返されるポインタの示す内容は,呼び出されるたびに破壊されます。
そのため,printf("\\%s.- \\%s.-\n",comma(x),comma(y)); のような使い方はできません。
ctrlbrk で,STOP キーの割り込みハンドラを設定しているが,^C が表示される
ctrlbrk 関数を使って,STOP キーが押された場合の割り込みハンドラを設定しているのですが,どうしても ^C が表示されてしまいます。 これを表示しないようにはできませんか?
STOP キーが押された場合は,^C が必ず標準出力に出力されます。 したがって,_close(1); などとして標準出力のファイルハンドルをクローズすれば表示されなくなります。 ただし,この場合は,printf などを使った普通の出力も使えなくなるので,cprintf など直接コンソールをアクセスする関数を使って表示するようにしてください。
#include <stdio.h>
#include <dos.h>
#include <io.h>
#include <conio.h>
int counter = 0;
int brk_handler(void)
{
counter++;
cprintf("STOP hit %d time%s\r\n",
counter, counter > 1 ? "s" : "");
return counter < 3 ? 1 : 0;
}
main()
{
ctrlbrk(brk_handler);
_close(1);
cprintf("Hit STOP 3 times to break!\r\n");
while (1) kbhit();
}
spawn 関数を使うと,リダイレクトできない。 system 関数では OK!
spawn 関数を使うと,正しくリダイレクトできません。 system 関数ではうまくいきます。
system 関数は COMMAND.COM を呼び出して子プロセスを実行します。 COMMAND.COM はリダイレクトを正しく処理しますが,spawn 関数は単独ではリダイレクトすることはできません。 次のようなプログラムで対応してください。
#include <io.h>
#include <fcntl.h>
#include <process.h>
#define s_in 0
#define s_out 1
main()
{
int oldhandle;
int newhandle;
/* 旧ハンドルの複製/退避 */
oldhandle = dup(s_out);
/* リダイレクトの対象となるファイルのオープン */
newhandle = _open("OUTPUT.FIL", O_WRONLY);
/* ハンドルの割り当て */
dup2(newhandle, s_out);
/* 子プロセスの実行 */
spawnl(P_WAIT, "CHILD.EXE", "CHILD.EXE", NULL);
/* リダイレクトファイルのクローズ */
_close(newhandle);
/* 旧ハンドルの復帰 */
dup2(oldhandle, s_out);
}
COM ファイルの作成方法は?
COM ファイルは,どのように作成すればよいのですか?
コマンドラインリンカ TLINK.EXE を使って直接 .COM ファイルを作成することができます。 このためには /t オプションを指定します。
次のコマンドラインは,TINY.EXE ではなく TINY.COM を作成します。
tcc -mt -lt tiny
この場合,-l オプションによって引数 /t がリンカに渡されます。
Turbo C++ のタイニィモデルで作成されたプログラムは,通常は .COM 形式に変換できますが,タイニィモデルのプログラムでは浮動小数演算ルーチンは使用できません。
初期化が正しく行われない
グラフィックスドライバを明示的に指定しているのに,初期化が正しく行なわれないのはなぜでしょう。
グラフィックスドライバを指定する場合は,グラフィックスモードも指定しなければなりません。 グラフィックスモードは,例えば PC98HI の場合は PC98C8,PC98C16 のいずれかです。
初期化時にメモリ不足のエラーが発生
BGI を組み込もうとしても,メモリ不足のエラーが発生して正しく組み込むことができません。
BGI は,通常 malloc を使ってドライバを組み込むためのメモリを確保します。 統合環境内で BGI を使ったプログラムを実行する場合は,使用可能メモリがかなり小さくなるため正しく動作しないことがあります。 また,スモールデータモデルでは,ヒープ領域が最大64KBしかないため,メモリが不足することがあります。 このときは, _graphgetmem,_graphfreemem をユーザプログラムで次のように再定義し,far ヒープ領域を割り当てることで対応できる場合があります。
#include <alloc.h>
#include <graphics.h>
void far * far _graphgetmem(unsigned size)
{
return farmalloc(size);
}
void far _graphfreemem(void far *ptr, unsigned size)
{
farfree(ptr);
}
registerbgidriver を使用。BGI ファイルが見付からないエラー
registerbgidriver を使ってドライバを登録しているのに,BGI ファイルが見つからない,といってエラーが発生します。
registerbgidriver は,あくまでも指定した BGI ファイルを実行ファイルに埋め込むだけで,その BGI ファイルを使うことを指定するのではありません。 このため,initgraph で DETECT を指定していると,埋め込んだ BGI ドライバと異なるものが検出された場合,カレントディレクトリに該当する BGI ドライバがなければエラーが発生します。 initgraph で,直接 BGI ドライバ名(およびモード) を指定するかすべての BGI ファイルを組み込んでください。
setbkcolor を指定すると黒で描画することができなくなる
BGI グラフィックスを使っていますが,setbkcolor を指定すると黒で描画することができなくなります。
バックグラウンドカラーのパレット番号は常に 0 です。 setbkcolor はパレット番号0 が表示する色を変更するだけで,バックグラウンドで使われるパレット番号を変更するわけではありません。 他の色を setrgbpalette などを使って黒 (R=0, G=0, B=0)を表示させるように変更するか,setbkcolor を使わずにプログラミングするようにしてください。
fillpoly で多角形の頂点の数が 680 以上になると,描画されなくなる
fillpoly で多角形の頂点の数が680以上になると,描画されなくなってしまうのはなぜですか。
グラフィックスルーチンの中には fillpoly や floodfill のようにバッファを用いるものがあります。 この場合は,setgraphbufsize でバッファサイズを増やしてください。 デフォルトのサイズは 4KB です。setgraphbufsize は initgraph より前に呼び出す必要があります。
outtext の実行速度を速くする方法は?
outtext の実行速度が遅いのですが,速くする方法はありませんか?
outtext の実行前に pc98crt(0x1b, 1); を呼び出すと,高速に描画されます。
ただし,テキスト画面の漢字がちらついたり (ノーマルモード),表示されなくなってしまうため (ハイレゾリューションモード),outtext の呼び出し後は,必ずpc98crt(0x1b, 0); を実行してください。
グラフィックスのハードコピーをとるには?
グラフィックスのハードコピーをとるにはどうすればよいのでしょう。
Turbo C++ の標準ライブラリには,ハードコピー用の関数は用意されていません。
マスターディスクの BGIUTILS.ZIP の中に,ノーマルモード用のハードコピーモジュール (PC-98 モノクロコピーのみ) が入っているので,これをご利用ください。
浮動小数演算エラーが発生すると,プログラムの動作がおかしくなる
浮動小数演算エラーが発生すると,プログラムの動作がおかしくなります。
EPSON の PC-286/386 シリーズでは,ディップスイッチ 3-8 がオフ (ノーマルモード) になっていると正しく例外が検出できないばかりか暴走の原因ともなりかねません。 このディップスイッチをオン (アドバンスモード) にして再度実行してください。
BIOS の詳細についての参考書は?
BIOS の詳細については何が参考になりますか?
「PC-9801 シリーズ テクニカルデータブック」 (アスキー出版局),「MS-DOS」(共立出版),「98 ハードに強くなる本」 (技術評論社) などが参考になるでしょう。
pc98clock で,日付/時刻を読み出すと,曜日がおかしくなっている
pc98clock で,日付/時刻を読み出すと,曜日がおかしくなっているようです。
DOS の DATE コマンドでは,正しく表示されています。
DOS は,内部で日付から曜日を計算していますが,pc98clock で呼び出される BIOS は,システムクロックが持っている曜日をそのまま返します。 このため,いったんシステムクロックの曜日がずれてしまうと,その後のシステムクロックの曜日は常にずれてしまうことになります。 pc98clock を使って,曜日を設定し直してください。
拡張 RS-232C ボードの通信速度が設定できません
拡張 RS-232C ボードの通信速度が設定できません。
拡張 RS-232C ボードの通信速度は,ボード上のディップスイッチで設定します。
拡張ボードを使用すると,文字の送信はできますが,受信ができません
拡張ボードを使用すると,文字の送信はできますが,受信ができません。
拡張ボードでの,文字の受信のために使われる割り込みベクタが,他のプログラムやハードウェアと競合しています。 たとえば,「FM 音源ボード」は割り込みベクター4番を使用するので,拡張ボードの割り込みベクターを変更しなければなりません (UV シリーズでは必ず変更してください)。 また,ハードディスクを増設している場合も,割り込みベクターが競合することがあります。 こうした場合は,ボード上のディップスイッチで,受信割り込みベクターを変更してください (詳細は,拡張ボードの取り扱い説明書をご覧ください)。
RS-232C で接続していますが,データの送受信ができません
2台のパソコンを RS-232C で接続していますが,データの送受信ができません。
設定した値が2台とも同じであるかどうか確認してください。 また,パソコンどうしの接続にはクロスケーブルが必要です。 pc98com...x 関数は,ROM-BIOS を利用しているので,RSDRV.SYS を組み込んでいるか連文節変換以前の DOS を使っている場合は,pc98com...x 関数は正しく動作しないことがあります。
pc98mouse でマウスでは,どのマウスドライバを組み込めばよいか?
pc98mouse でマウスの制御を行ないたいのですが,どのマウスドライバを組み込めばよいのでしょう。
マウスドライバは,DOS に付属している MOUSE.SYS を組み込んでください。
CONFIG.SYS ファイルの中に DEVICE=MOUSE.SYS という行を付加します。 なお,古いマウスドライバの中には,スタックの消費量が多く場合によってはプログラムの実行に支障をきたすものがありますので注意してください。 Microsoft 形式のマウスドライバには対応していません。 Microsoft 形式のマウスドライバを利用するためには,int86 や int86x を利用してください。
マウスと BGI を併用させるには?
マウスとグラフィックス(BGI)を併用させるには,どうすればよいでしょうか?
グラフィックス命令で,表示中のマウスカーソル上に描画を行なうと,マウスの“あと”が残ってしまうことがあります。 マウスカーソルの表示領域と,グラフィックスの描画領域が重なる場合は,いったんマウスの表示を停止してください。
setvisualpage で,1 を設定すると,マウスカーソルが表示されなくなる
pc98mouse を使っていますが,setvisualpage (表示画面の設定) で,1(裏画面)を設定すると,マウスカーソルが表示されなくなってしまいます。
マウスカーソルは,常に描画画面にあります。 描画画面と表示画面が異なる場合は,マウスカーソルは表示されません。
pc98timer で設定した関数が,一度しか実行されない
pc98timer で設定した関数が,一度しか実行されません。
pc98timer で設定した関数を連続的に実行させるためには,設定する関数の内部で,再度 pc98timer を呼び出し,自分自身を設定し直さなければなりません。
64KB 以上のデータはどのように参照したらよいでしょうか?
far ポインタを宣言しましたが,64KB を超えてインクリメントしたときにオフセットだけ元に戻ってしまいました。 64KB 以上のデータはどのように参照したらよいでしょうか?
huge ポインタを使ってください。 ヒュージモデルでコンパイルした場合も,デフォルトのポインタは far として扱われます。
huge の配列を使ったが,64KB を超える部分にアクセスできない
該当するバージョン: Turbo C++ 1.0, Turbo C++ 4.0
64KB を超える配列を確保するために huge を使ったのですが,64KBを超える部分にアクセスできません。
Turbo C++ の統合環境は,64KB を超える huge 配列の要素を正しくアクセスしません。 また,huge 配列に対して直接数値で添字を与えた場合,64KB を超える部分に正しくアクセスできないことがあります。 この場合は,いったん long 型の変数に値を代入して変数を添字として指定するか,huge 配列名を huge ポインタに代入して,ポインタでアクセスするように変更してください。
割り込みハンドラから呼び出す関数でスタックオーバーフロー
該当するバージョン: Turbo C++ 1.0, Turbo C++ 4.0
interrupt 修飾子を使って割り込みハンドラを記述していますが,そこから呼び出している関数で必ずスタックオーバーフローになってしまいプログラムが異常終了してしまいます。 プログラムでは,それほど多くのスタックを使っていません。
ハードウェア割り込みの処理ルーチンが呼び出されたときに使われるスタックは,必ずしもそのプログラムが確保したスタックであるとは限りません。 たとえば,DOS ファンクションの呼び出し中にハードウェア割り込みがかかったときは,DOS ファンクションのためのスタック領域が割り込みハンドラで使われます。 スタックチェックオプションは,プログラムが確保したスタック領域しかチェックしないので,これ以外のスタックが使われているときには正しく機能しません。
割り込みハンドラから呼び出される関数を含むモジュールはスタックチェックオプションを外してコンパイルするようにしてください。 また,ソースコード中で #pragma option -N- と指定すれば,それ以降の関数はスタックチェックが行なわれなくなります。
日本語フロントプロセッサ(FEP)のオン/オフを制御したい
かな漢字変換フロントプロセッサ (FEP) のオン/オフを制御したいのですが,簡単な方法はありませんか?
マスターディスク1枚目に FEPCTRL というモジュールが用意されています(FEPCTRL.ZIP というファイルに圧縮して格納されています)。 詳細は,この中のREADME.FEP および FEPCTRL.DOC をご覧ください。
日本語フロントプロセッサ'(FEP)とPC-H98の拡張アトリビュート
かな漢字変換フロントプロセッサ (FEP) を組み込んでいますが,IDE で PC-H98 の拡張アトリビュートを使うと,システムラインが正しく表示されません。
FEP によっては,PC-H98 の拡張アトリビュートに対応していないものがあります。
この場合は,コマンドラインオプション -a- を指定して,拡張アトリビュートを使用しないようにしてください。 拡張アトリビュートの対応の詳細については,各FEP のメーカーにお問い合わせください。
Win32s のバージョン情報
Win32s を含む製品とその製品に含まれる Win32s のバージョンの一覧は以下のようになります。
Product
Version
Borland C++ 4.0J
1.15
Borland C++ 4.5J
1.20
Turbo Assembler 4.0J
1.15
Language Q&A に戻る |
Q&A ホームページへ戻る
Trademarks & Copyright (C) 1998 INPRISE Corporation. Last modified on 8-June-1998.