DLL作成の機会がいろいろ調べているのですが、教えていただきたいことがあります。
1.インポートライブラリについて
 Windowsで暗黙的リンクでDLLをリンクする場合、
 インポートライブラリを利用するようですが、
 これは、DLL内のポインタと関数名を紐付けるような
 役割だと想定しています。
 仮に関数等ヘッダーで公開されている部分以外で
 DLLを更新した場合、インポートライブラリも
 再リンクするような場面があるのでしょうか。
 特に再リンクしなくてもDLLの更新が反映されたので・・
2.DLLのクラスの継承について
 DLL内に作成したクラスを継承することは不可能ですかね。
 DLLが更新された場合、インスタンスのイメージが違うため
 newやdeleteの処理で当初リンクしたインスタンスのイメージで
 行いますよね。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

>>"DLLのデーター"は”アプリのデーター領域”に配置される


>>という認識は間違いですか?

>間違いですね。(あっさり)

間違いですか。
では、"DLLのデータ"はどこに配置されるのでしょう?
呼びだし側に"DLL専用”の領域が新規にできるのですか?

できたら論拠となるMSDNのページを示して頂きたいです。
(日本語が良いですが、機械翻訳でわかりずらいページも多いです。
でしたら、英語でも構いません。)

>継承クラスをインスタンス化したときに
>領域が取られるわけですが、DLLのインスタンス部分の
>サイズはDLLによって定義されるのではないか

具体的に考えましょう
class Base
{
int m_BaseMember1;
};

なるクラスがDLLからエクスポートされているとします。
clas Ext : publc Base
{
int m_ExtMember1;
}
という風にアプリで派生させ、Extのオブジェクトを作成したとします。
int = 32ビット前提で考えますと
Baseオブジェクトの大きさは4バイト
Extオブジェクトの大きさは8バイトです。
(Base部分4バイト、Ext独自部分4バイト)

今Baseを修正し, int m_BaseMember2を追加したとします。
つまり
class Base
{
int m_BaseMember1;
int m_BaseMember2;
};

となったとします。
Extには変更なしとします。

新たなExtのサイズは12バイトです。
(Base部分8バイト、Ext独自部分4バイト)

このように基本クラスのインスタンスが
派生クラスのインスタンス中に完全に取り込まれるのは
DLLだろうと普通のアプリだろうと同様です。

DLLの場合は、
(基本クラスを取り込まずに)
ポインタでつなぐので
基本クラスのサイズが増えても
派生クラスのサイズは影響を受けない

などとはなっていません。
    • good
    • 0
この回答へのお礼

返答が遅くなり申し訳ないです。
>このように基本クラスのインスタンスが
>派生クラスのインスタンス中に完全に取り込まれるのは
>DLLだろうと普通のアプリだろうと同様です。
ではやはり、基本クラスの更新に伴って、派生クラスのコンパイルが必要に
なってくるのですね。
ありがとうございます。

お礼日時:2009/05/26 15:31

>アプリで定義した継承クラスを new した場合、


>DLLで定義した基底クラスのインスタンスはDLLのデーター領域にでき、
>アプリで定義した継承クラスの部分はアプリのデーター領域にできる・・?

あのーーー
"DLLのデーター領域"と”アプリのデーター領域”の違いがよくわかりません。
説明をお願いします。

http://msdn.microsoft.com/ja-jp/library/h90dkhs0 …
によりますと

”Win32 DLL は、呼び出し側プロセスのアドレス空間に割り当てられます。
既定では、DLL を使用するプロセスごとに、
すべての DLL のグローバル変数および
静的変数のインスタンスが作成されます。”

素直によむと
DLLのデータは呼び出し側プロセス(アプリのことですね)
のデータ領域に配置される
ように解釈できます。

ですから、私には
"DLLのデーター領域"と”アプリのデーター領域”の違いがわかりません。
"DLLのデーター"は”アプリのデーター領域”に配置される
という認識は間違いですか?
    • good
    • 0
この回答へのお礼

間違いですね。(あっさり)
というより表現が適切ではなかったと思っています。
アプリが起動したときにDLLを読み込み
継承クラスをインスタンス化したときに
領域が取られるわけですが、DLLのインスタンス部分の
サイズはDLLによって定義されるのではないかと考えている
ということです。

お礼日時:2009/05/24 09:47

DLLについてはこちらで詳細に解説されています。


http://msdn.microsoft.com/ja-jp/library/7h0a8139 …

MSDNにはWindows上での開発に関わる情報がたくさんあります。
わからないことがあったら、MSDNで調べてみましょう。

DLLですが、一般のアプリと変わりません。

あえて注意する点といいますと
常駐オブジェクトの扱いですね。

C++では良く"資源管理はコンストラクタ"と言われます。
コンストラクタ中でメモリを確保し、
デストラクタで廃棄するのがお決まりパターンとなっています。

しかし、この方法はDLL内のstaticオブジェクトには向かないようです。
(staticでなく、アプリが自分で構築する分には問題ない)
コンストラクタとは別の初期化関数を用意し、
アプリから明示的に呼ぶ方法が無難なようです。

特に、オブジェクトがスレッドを抱え込んでいて、
オブジェクトの生成と同時にスレッドも起動したい場合、
DLL内常駐オブジェクトでは絶対と言っていいほどできません。

各種常駐オブジェクトの初期化関数呼び出しを一個の関数に
まとめて"ライブラリ初期化関数"としてエクスポートし、

”DLLを使う際には、最初に初期化関数を呼んでね"

というお約束にしとく手をよく使います

(後始末も同様です)
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。
勉強になります。
> DLLですが、一般のアプリと変わりません。
アプリで定義した継承クラスを new した場合、
DLLで定義した基底クラスのインスタンスはDLLのデーター領域にでき、
アプリで定義した継承クラスの部分はアプリのデーター領域にできる・・?

お礼日時:2009/05/24 08:40

>仮に関数等ヘッダーで公開されている部分以外で


> DLLを更新した場合、インポートライブラリも
> 再リンクするような場面があるのでしょうか。

再リンクの必要はありません。

>DLL内に作成したクラスを継承することは不可能ですかね。
可能です。
実際、MFCユーザーはよくやっていることですよね。
MFCを"ダイナミック・リンク"して、
MFC内のCViewやCDialogから
アプリ側で派生クラスをこしらえるのは、
ごく普通にできていることです。

ただし、前提条件があります。
更新前と更新後で同一の処理系を使うことです。

C++は関数の多重定義を解決するため、
関数名に変更を加えます。
その変更方法は、
完全に(処理系の)デベロッパに委ねられており、
統一が図られていません。

A社の処理系で作成したDLLを利用して
アプリを作り
B社の処理系でビルドすることはできません。

DLLも含めて、全体を
B社の処理系で
リビルドすれば問題はなくなります
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

> 再リンクの必要はありません。
やはりそうなのですか。
バイナリエディタで開くと関数名しかないので
関数の定義をしているだけなのですね。

> 実際、MFCユーザーはよくやっていることですよね。
> MFCを"ダイナミック・リンク"して、
> MFC内のCViewやCDialogから
> アプリ側で派生クラスをこしらえるのは、
> ごく普通にできていることです。
そういえば・・
よろしければやり方をご教示いただけるとありがたいです。
気になるのはインスタンスの生成と開放の部分なのですが、
その他処理系の問題以外に注意しなければならないところなどあれば
お願いいたします。

お礼日時:2009/05/23 19:02

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qfatal error LNK1120: 外部参照 1 が未解決です

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
  char tel[20];
  char address[20];
};

void message( void );
void input( FILE *fp, int cnt , struct meibo *a, int *end );

void main( void )
{
  struct meibo a[20];
  FILE *fp;
  int cnt, end;

  if( (fp=fopen( "meibo.dat", "w" ) ) == NULL ){
    printf( "Can not open the meibo.dat.\n" );
    exit( 1 );
  }

  message();

  fprintf( fp, "番号, 名前, TEL, 住所\n" );
  fflush( fp );

  cnt = 0;
  end = 0;
  while( end == 0 ){
    input( fp, cnt, &a[cnt], &end );
    cnt++;
    fflush( fp );
    if( cnt == 20 ){
      printf( "人数が一杯です.終了します.\n" );
      end = 1;
    }
  }
  fclose( fp );
}

void message( void )
{
  printf( "名前, TEL, 住所, endを入力してください.\n" );
  printf( "継続の時はend=0," );
  printf( "中止の時は,end=1と入力してください.\n" );
}

void input( FILE *fp, int cnt, struct meibo *a, int *end )
{
  printf( "名前-->" );
  scanf( "%s", a->name );
  printf( "TEL -->" );
  scanf( "%s", a->tel );
  printf( "住所-->" );
  scanf( "%s", a->address );
  printf( "Exit? Continue:0 Exit:1 -->" );
  scanf( "%d", end );
  printf( "\n" );
  fprintf( fp, "%2d, %s, %s, %s\n",
    cnt+1, a->name, a->tel, a->address );
}

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
...続きを読む

Aベストアンサー

http://www.a.math.ryukoku.ac.jp/~hig/course/compsci2_2005/man/faq.html
にある現象と同じではないでしょうか、一度お試しください。

QcharからLPTSTRへの変換方法

リストコントロールにchar型の変数の値を数値として表示させたいのですが、charからLPTSTRへの洗練された変換方法がよくわからないです。

char tempChar;
CString tempString;
tempString.Format("%s", tempChar);
LPTSTR lpsz = new TCHAR[tempString.GetLength()+1];
_tcscpy(lpsz, tempString);

こんなプログラムを考えてみたのですが、汚いような気がします。もっと簡単で洗練された変換方法はないのでしょうか?

Aベストアンサー

wsprintfを使ってはどうでしょうか?

char tmpChar = 100;//表示する数値
TCHAR buf[5];
wsprintf(buf, "%d", tempChar);

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Q「fatal error C1189」を回避するには?

かなりの初心者でございますm(__)m。

先日のことですが「Visual Studio .net 2003」から「Visual Studio 2005」へアップグレード(というよりは切り替え)を行いました。

すると2003では問題なくビルド出来たものが2005では「fatal error C1189」が出てしまい困っております。

エラーメッセージ
fatal error C1189: #error : Need to include strsafe.h after tchar.h

確かにtchar.hはインクルードしているので、これを文字通りに解釈して後にstrsafe.hをインクルードしたのですが、メッセージは変わらず(--;)。

どの辺りをチェックしたら良いか教えていただけると助かります。

OSはXP、VisualStudioのSP1はあてていません(エラーでSP1がインストール出来ないため)。

Aベストアンサー

C1189 はコンパイル指令 #error によるものらしいので
Fatal Error C1189 (C++)
http://msdn2.microsoft.com/en-us/library/y0tzt8e0(VS.80).aspx

#error Need to include strsafe.h after tchar.h

というのを検索してみると、
vc/include/tchar.h に

#ifdef _STRSAFE_H_INCLUDED_
#error Need to include strsafe.h after tchar.h
#endif

というのが見つかりました。

tchar.h, strsafe.hのほかにどんなファイルを includeしているか
わかりませんが、間接的にでもどこかから strsafe.h をすでに
読みこんでしまっているということはありませんか?
そうでもなければこのシンボルが定義されることはないように思うのですが。

ざっと見たところ、vc8/include と vc8/PlatformSDK/include には
strsafe を独自に取り込むようになっているファイルはないですね。
#まあ当然か

C1189 はコンパイル指令 #error によるものらしいので
Fatal Error C1189 (C++)
http://msdn2.microsoft.com/en-us/library/y0tzt8e0(VS.80).aspx

#error Need to include strsafe.h after tchar.h

というのを検索してみると、
vc/include/tchar.h に

#ifdef _STRSAFE_H_INCLUDED_
#error Need to include strsafe.h after tchar.h
#endif

というのが見つかりました。

tchar.h, strsafe.hのほかにどんなファイルを includeしているか
わかりませんが、間接的にでもどこかから strsafe.h をす...続きを読む

QMFCアプリのコマンドラインでパラメータを使用した起動方法

VisualC++6.0を用いて、ダイアログの2つあるプログラムを
作ったのですが、
2つのダイアログを例えばAさん用、Bさん用として使い分けようと思ったときに
メニューでダイアログをそれぞれ指定して、実行しようと思ったのですが、
Aさん用を親ダイアログにしてしまうと、Bさんは起動時ごとにメニューで
切り替えなければいけなくなりますよね。
それで、切り替えをしなくても良いようにと思って、
コマンドラインからパラメータで「/A」「/B」などとしたときに、Aさん用
Bさん用として、起動させたいのですが、
コマンドラインのパラメータをどこで受け取って処理しているのか
分らないのですが、教えては頂けないでしょうか?
よろしくお願い致します。

Aベストアンサー

補足です。
WinAPPクラスInitInstance関数のなかで、
>CCommandLineInfo cmdInfo;
>ParseCommandLine(cmdInfo);
の記述があればそのあとでパラメータの解析を行います。>>m_lpCmdLineです。

もし、作成中のプロジェクトにこの記述がない
(InitInstance関数がない等の)場合は、
CCommandLineInfoクラスの継承クラスをつくって
仮想関数
virtual void CCommandLineInfo::ParseParam(LPCTSTR lpszParam, BOOL bFlag, BOOL bLast)
を実装しましょう。

たとえば・・・

CWinApp theApp;
using namespace std;


// コマンドライン解析クラス
class CMyClass : public CCommandLineInfo{
public:
virtual void ParseParam(LPCTSTR, BOOL, BOOL);
};

//コマンドラインの個々のパラメータを解析および解釈するために、フレームワークが呼び出します
void CMyClass::ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL bLast )
{
CString strTemp = _T(lpszParam); // パラメータ、またはフラグ
return;
}

void
main()
{
CMyClass info;
theApp.ParseCommandLine(info);
}

では^^。

補足です。
WinAPPクラスInitInstance関数のなかで、
>CCommandLineInfo cmdInfo;
>ParseCommandLine(cmdInfo);
の記述があればそのあとでパラメータの解析を行います。>>m_lpCmdLineです。

もし、作成中のプロジェクトにこの記述がない
(InitInstance関数がない等の)場合は、
CCommandLineInfoクラスの継承クラスをつくって
仮想関数
virtual void CCommandLineInfo::ParseParam(LPCTSTR lpszParam, BOOL bFlag, BOOL bLast)
を実装しましょう。

たとえば・・・

CWinApp theApp;
using name...続きを読む

Qラッパーって何なんでしょう・・・?

C++を勉強し始めたのですが、何とも難しい言葉が多くて、書いてあることが本当に理解できません。
ラッパーって?
ハンドルって??
と、次から次へと理解不能な言葉が・・・
読んでいるのは、C++Builderの開発者ガイドと、プログラミング言語C++の本です。
具体的なイメージが浮かばず、概念自体もピンときません。
わかりやすい本などあったら教えてください。
また、とりあえずラッパーとハンドルがどうしても気になるので、この2つの意味教えてください!!
よろしくお願いします。

Aベストアンサー

ラッパーは、wrapper で包み込むものの意味です。
wrap ラップはサランラップのラップですね。
wrappingラッピングといえば、プレゼントを包むやつですね。

つまり、たとえばある関数を使いたいと思ったとします。
しかし、その関数を呼び出すには、いろんな手続きをしないといけない、また呼ぶときに渡す引数をたくさん設定しなければならないなど、使用するのが面倒な場合があります。
これはその関数が汎用的に使えるように、動作に自由度を持たせていると、面倒になる傾向にあります。

そんな時、引数なし、又は簡単な引数で呼び出せるような関数を作ってあげれば楽になります。
この場合は、ある程度用途が決まっているので、その関数を呼び出すときの手続きを省略してくれるような関数ですね。
それがラッパーというわけです。

あと良くあるのが、C言語で書かれたライブラリなどをC++の機能を使って使いたいときに、ラッパーを作ったりします。
この場合は逆に機能を追加して使いやすくするイメージですね。

ハンドル(handle)はつまり何かを操作するときのハンドル(車のハンドルと同じ)です。

この概念は良く使われます。
たとえば、ハードディスクにはファイルがたくさん入っています。
その中のファイルを開いて何か処理しようとします。するとディスクアクセスの処理をしなければなりませんが、それを自分で書くのは大変なので、ライブラリを使います。
ライブラリでは、
・指定されたファイルを開く関数
・指定されたファイルの中身を読み出す関数
・指定されたファイルに指定の文字を書き出す関数
などなどたくさん用意します。

ここで一つ問題が生じます。もし複数のファイルを同時に処理したい場合どうやったらよいでしょう。
いちいちファイル名で指定する方法も考えられますが、ファイルを開くときに一つのハンドルという名前の変数を用意し、その変数の中にどのファイルであるという情報、そのファイルのサイズ、そのほか必要な情報を一つにまとめておくと、ファイルを操作するときにはその変数を引数として渡すだけで、ファイルがどれであるのかという指示が簡単に出来ます。

いまファイルハンドルを例にあげましたが、他にもWindowsではたくさんのWindowを開きますので、それら一つ一つにもハンドルが用意されています。

基本的に、

・同種のものが複数ある
・上記に対して操作する関数が複数ある

という条件を満たすようなものに対しては、ハンドルという概念でコントロールすることがよくあります。

ラッパーは、wrapper で包み込むものの意味です。
wrap ラップはサランラップのラップですね。
wrappingラッピングといえば、プレゼントを包むやつですね。

つまり、たとえばある関数を使いたいと思ったとします。
しかし、その関数を呼び出すには、いろんな手続きをしないといけない、また呼ぶときに渡す引数をたくさん設定しなければならないなど、使用するのが面倒な場合があります。
これはその関数が汎用的に使えるように、動作に自由度を持たせていると、面倒になる傾向にあります。

そんな時、引...続きを読む

QC言語のコンパイルエラーなんですが、どこが悪いのかがわからない。

 作成したソースプログラムを、コンパイルしようとすると次のようなエラーが出ます。
「ファイル名:19:waring: unknow escape sequence: `\' followed by char code 0×89」

 確かに、19行めに¥nの改行コードを打ちましたがそれがいけないのかな?しかし、その理由もわからん。
 というか、上の考えがあっているのかすら分からない。どうか教えてください。ちなみに、19行目のソースプログラムは

「printf("よし!十円チョコかえるわ。今すぐレッツゴー。\n");」

です。よろしくお願いします。

Aベストアンサー

これはUNIXではありがちなエラーで、原因は文字コード(シフトJIS)にあります。

ここで問題になっているのは「十円」という部分で、これを16進で出力すると「8F 5C 89 7E」となります。
5C は \ の文字コードであるため、これをエスケープ文字として認識し、次に続く 89 を見て「そんなエスケープシーケンスはない」というエラーを出しているのです。

解決方法ですが、5C をエスケープコードではなく \ 自身であるように認識させればよいので、5C の後ろにもう1つ 5C を置いてやればOKです。
つまり、「十円」を「十\円」とします。

※日本語環境用に作られたコンパイラは、その辺をきちんと処理してくれるのでこのような問題は起きないのですが、そうでないコンパイラでは注意が必要になります。

Q構造体配列を引数とするDLL作成し、VBで呼ぶには?

はじめまして。
VisualC++6.0でDLLを作り、VisualBasic6.0にて
VisualC++の関数をコールし、構造体配列の値を
渡そうとしていますがうまくいきません。
どなたかよい知恵をお貸しください。
宜しくお願い致します。
下記に、VisualC++6.0とVisualBasic6.0のやりとり
を記します。

*====Visual C++ 6.0側=====
typedefstruct_DLP_MSGDATA
{
intflg;
charmsg[504];
inttmp;
} DLP_MSGDATA;

_declspec(dllexport) int _stdcall SampSub(int data, DLP_MSGDATA *mdata)
{

return( 0 );
}


*====Visual Basic 5.0側=====
Declare Function SampSub Lib "test.dll" Alias "_SampSub@8" _
( _
ByVal tlp_id As Long, _
ByRef mdata() As DLP_TLP_MSGDATA _
) As Long


Type DLP_TLP_MSGDATA
flg As Long
msg As String * 504
tmp As Long
End Type

Private Sub test()
Dim mdata(0 To 130) As DLP_TLP_MSGDATA
Dim aa As Long

Call SampSub( aa, mdata )

End sub

はじめまして。
VisualC++6.0でDLLを作り、VisualBasic6.0にて
VisualC++の関数をコールし、構造体配列の値を
渡そうとしていますがうまくいきません。
どなたかよい知恵をお貸しください。
宜しくお願い致します。
下記に、VisualC++6.0とVisualBasic6.0のやりとり
を記します。

*====Visual C++ 6.0側=====
typedefstruct_DLP_MSGDATA
{
intflg;
charmsg[504];
inttmp;
} DLP_MSGDATA;

_declspec(dllexport) int _stdcall SampSub(int data, DLP_MSGDATA *mdata)
{

return( 0 ); ...続きを読む

Aベストアンサー

(2)の方法で問題ないと思いますが..

'第2引数の型をAnyに変更
Declare Function SampSub Lib "test.dll" Alias "_SampSub@8" _
( _
ByVal tlp_id As Long, _
mdata As Any _
) As Long

Declare Sub MoveMemory Lib "kernel32.dll" _
Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)

ReDim bdata(131 * Len(mdata(0))) As Byte

'構造体の配列をbyte配列にコピー
For i = 0 To 130
MoveMemory bdata(i * Len(mdata(0))), mdata(i), Len(mdata(0))
Next
Call SampSub(1, bdata(0))
'byte配列を構造体の配列にコピー
For i = 0 To 130
MoveMemory mdata(i), bdata(i * Len(mdata(0))), Len(mdata(0))
Next

(2)の方法で問題ないと思いますが..

'第2引数の型をAnyに変更
Declare Function SampSub Lib "test.dll" Alias "_SampSub@8" _
( _
ByVal tlp_id As Long, _
mdata As Any _
) As Long

Declare Sub MoveMemory Lib "kernel32.dll" _
Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)

ReDim bdata(131 * Len(mdata(0))) As Byte

'構造体の配列をbyte配列にコピ...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報