<VC++で作成したDLLをVBで呼ぶ処理>
DLL側でメモリ割り当てを行ったあと、VB側でメモリ解放を
したいのですが、方法がわかりません。
教えてください。

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

A 回答 (3件)

こんにちは。

itohhといいます。

mallocで確保されたエリアは開放できないと思います。
なぜなら、VBからでは、Free関数が直接呼べないからです。

もし、どうしてもVBで解放したいのであれば、malloc関数の代わりに
GlobalAlloc関数を使用してください。
そのときのハンドルを返すようにすることによってGlobalFree関数(解放する関数)
を使用することが出来るようになります。

関数の対応は、
malloc関数 -> GlobalAlloc関数(およびGlobalLock関数)
Free関数  -> GlobalFree関数(およびGlobalUnlock関数)
です。
    • good
    • 0

こんにちは。

itohhといいます。

DLL側で動的にメモリを割り当てた場合は、解放しなければいけません。
(メモリリークしてそのうち再起動しなければいけなくなります。)

ご自分でDLLを作成しているのでしょうか?
それならば、DLLで解放する関数を作成しては如何ですか?

この回答への補足

DLL側でmallocなどでメモリ割り当てをした場合、
VB側ではメモリ解放はできないという事でよろしいのでしょうか?

補足日時:2001/09/19 10:07
    • good
    • 0

VBの変数スコープの範囲で動的に廃棄しますので


なにもしなくてよい

下記ATLの場合
sub vfHoge
 dim sFunctonName as string
 sFunctionName = oHoge.FunctionName
endsub 'ここでsFunctonNameの領域開放

STDMETHODIMP CBSFDevKit::get_FunctionName(BSTR *pVal)
{
 *pVal = ::SysAllocString(m_sFunctionName);
 return S_OK;
}

この回答への補足

VBもVC++も初心者なので見当違いだったらすみません。

VC++のDLL側で割り当てたメモリもVB側から参照しただけで
解放されるのでしょうか?
VC++でいうfreeのような事はしなくていいのでしょうか?

確認のためお願いします。

補足日時:2001/09/18 21:25
    • good
    • 0

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

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

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

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

Q文字列を返すVCで作成したDLL関数をVBで呼ぶと...

VC++で文字列を返すDLL関数を作成しました。

LPCSTR GetVcString(void)

これをVBでStringとして受け取り、MsgBoxで表示すると正常に取得できているようなのですが、Lenで文字数を取得すると変な値が返ってきます。

1. Dim Ret As String
2. Ret=GetVcString()
3. MsgBox(Ret) ← VCで返された文字列は正常に表示されている
4. MsgBox(Str(Len(Ret))) ← 実際の文字数とはかけ離れた数値になる

2行目と3行目の間に、
Ret=Left(Ret,InStr(Ret,vbNullChar)-1)
を噛ませれば文字数は正常な値になるのですが、このような処理をしなくても正常に文字数を取得する方法があれば教えてください。

Aベストアンサー

こんにちは。maruru01です。

関数が返す文字列が、固定長で残りの部分がvbNullCharで埋まっているので、vbNullCharの手前までを抜き出す処理を入れなければいけません。
WinAPI関数などでは、このようなことはよく見られます。
単に文字数を出したいなら、

MsgBox(InStr(Ret, vbNullChar)-1)

でいいと思いますが。
でもその後でいろいろと処理するなら、

Ret=Left(Ret,InStr(Ret,vbNullChar)-1)

を入れた方がいいと思います。
たかが1行だし。

QCで作成したDLL関数をVBから呼ぶ

以前にあった「Cで作成したDLL関数をVBから呼び 引数渡し方法」を試したのですがVB側でデータが受け取れません。

http://oshiete1.goo.ne.jp/kotaeru.php3?q=711327

C側での値設定がわるいのでしょうか?

VB側
Public Declare Function testAP Lib "C:\bin\test.dll" (ByVal lpKeyData As String) As Long
---------------------------------------------------------------------------
Dim lngRc As Long
Dim keydata As String * 128

keydata = String$(128, Chr(0) & Chr(0))
lngRc = testAP(keydata)

VC側
__declspec(dllexport) long __stdcall testAP(char *lpdata){
→C側でlpdataに値を設定する
lpdata="ABCDEF";
}

以前にあった「Cで作成したDLL関数をVBから呼び 引数渡し方法」を試したのですがVB側でデータが受け取れません。

http://oshiete1.goo.ne.jp/kotaeru.php3?q=711327

C側での値設定がわるいのでしょうか?

VB側
Public Declare Function testAP Lib "C:\bin\test.dll" (ByVal lpKeyData As String) As Long
---------------------------------------------------------------------------
Dim lngRc As Long
Dim keydata As String * 128

keydata = String$(128, Chr(0) & Chr(0))
lngRc = testAP...続きを読む

Aベストアンサー

VC側のlpdataの設定が違っています。
ポインタの代入ではなく、文字列のコピーにしてください。

VC側
__declspec(dllexport) long __stdcall testAP(char *lpdata){
→C側でlpdataに値を設定する
strcpy(lpdata,"ABCDEF");
}

Qvc++のAPI(dll)の引数をVBAでうけとる

Excelで開発しなければならない事情があり、
vc++のAPIが持っている関数を
ExcelVBAでコールしておりますが、エラー1041でExcelが強制終了してしまいます。
VBAからVisual C++にchar*型で渡し、ByRef String型でVBAにて受け取ります。

VCの関数の第四引数「char* 型/attribute_value」をVBAの「String 型/sValue」で受け取る際にエラーになっているようです。

VBAでcharに相当する変数型がないためと思われますが、何かよいアイデアがありましたらご教授願います。

--VC--
XDW_GetDocumentAttributeByName(h, attribute_name, &attribute_type, attribute_value, size, NULL);
--VBA--
<宣言部>
Public Declare Function XDW_GetDocumentAttributeByName Lib "C:\Users\○○○\Desktop\dwsdk710jpn\XDWAPI\DLL\xdwapi.dll" (ByVal lnghandle As Long, ByVal sName As String, ByRef lngType As Long, ByRef sValue As String, ByVal lngSize As Long, ByVal reserved As String) As Long

<呼び出し部>
Dim lngHandle As Long
Dim sName as String
Dim lngType As Long
Dim sValue As String
Dim lngSize as Long
Dim tmpSize as Long
lngSize = 0
sName = "keiyaku"

tmpSize = XDW_GetDocumentAttributeByName(lngHandle, sName, sType, sValue, lngSize, vbNullString)

XDW_GetDocumentAttributeByName lngHandle, sName, sType, vbNullString, tmpSize, vbNullString
degug.print sValue

Excelで開発しなければならない事情があり、
vc++のAPIが持っている関数を
ExcelVBAでコールしておりますが、エラー1041でExcelが強制終了してしまいます。
VBAからVisual C++にchar*型で渡し、ByRef String型でVBAにて受け取ります。

VCの関数の第四引数「char* 型/attribute_value」をVBAの「String 型/sValue」で受け取る際にエラーになっているようです。

VBAでcharに相当する変数型がないためと思われますが、何かよいアイデアがありましたらご教授願います。

--VC--
XDW_GetDocumentAttributeByName(...続きを読む

Aベストアンサー

XDW_GetDocumentAttributeByNameのなかで sValueに文字列を設定するのであれば
あらかじめ sValueにデフォルトの文字列を与えておいて呼び出すようにしてやればいいでしょう

APIの記述は ByVal sValue as String で行います

Dim sValue as String * 256
といった固定文字列
Dim sValue as String とするならば
DLLを呼ぶ前に
sValue = Space(256)
といった具合に初期化しておきます

DLLを呼び出す場合には Unicode/Ansi変換を自動で呼び出すと思います
VBA側にリターンしてから逆変換をしますし ・・・

QVBでVC++の処理速さを実現する

ふと疑問に思ったので質問します。

あくまでも一般論ですが、VBはVC+より簡単だけどデメリットは処理速度が遅いことだそうです。

でもどちらも最終的には機械語?に訳されるんでしょ?

じゃあ人間にとって作りやすいVBで作っても、最終的にはコンパイラがVC++と同じ機械語にしてくれたら良いと思うのですが。

どうしてそういう都合の良いことは出来ないのですか?

Aベストアンサー

なんかいろいろと話が出てますが。

本質的にVBとVC++の違いは

>あくまでも一般論ですが、VBはVC+より簡単だけどデメリットは処理速度が遅いことだそうです。

ですよね。

で、”簡単”というところでVBがどうして簡単なのかを考えていけばわかると思います。

簡単な理由:
1.データ型を意識しなくても自動的に変換してくれる
・・・VBが内部的にがんばって変換する処理を行っている

2.文字列が簡単に扱える。
・・・VBが内部的に、領域確保やメモリ内のデータのコピーなどの処理をがんばってる。

3.画面にコントロールを貼り付けるだけで、簡単にGUIが完成する。
・・・VBがフォームの表示等の一般的な必要となる処理、コントロールとのやり取りの処理等をすべて内部的に行っている。

4.ActiveXコンポーネントやCOMオブジェクトが簡単に使える。
・・・VBが内部的なコンポーネントとのインターフェイス間のやり取りをすべて行っている。

みたいな感じですかね?

ランタイムが必要とか、コンパイルが必要とかということとは別問題です。

ランタイムは、あくまでもVBのプログラムで内部的に共通で
行われる処理をまとめてDLL等にしたり、
VBで直接使用しづらい処理をActiveXコンポーネントにすとといったために使用します。

コンパイルも、ちゃんとネイティブコンパイルできますし。

で、このVBの簡単な点が全て実行速度というところに跳ね返ってきます。


2.やランタイムについては、VitaminBBさんはMFCをよく使われているのであれ?と思ったかもしれません。

MFCはCStringで簡単に文字列を扱えますし、MFCにはランタイムDLLも存在します。

実は、MFCもVBほどではないですが、”遅い”です。
フレームワークがC++で書かれているから速いとか言う問題ではなく、単純に、ある程度何でもできるフレームワークだから内部的な処理が多すぎるという点でMFCは遅いのです。

つまり、便利→内部的な処理が多い→遅いということになります。

#ただ、MFCの場合は、画面まわり、すなわちユーザーインターフェイスをMFCに任せ、演算などの高速処理を必要とするビジネスロジックはMFCを使わないということもできるので、このあたりがVBと違うところです。
VBで速くしようとすると、画面はVB、ビジネスロジックはCのDLLなんてことになります(よくありますが)。

なんかいろいろと話が出てますが。

本質的にVBとVC++の違いは

>あくまでも一般論ですが、VBはVC+より簡単だけどデメリットは処理速度が遅いことだそうです。

ですよね。

で、”簡単”というところでVBがどうして簡単なのかを考えていけばわかると思います。

簡単な理由:
1.データ型を意識しなくても自動的に変換してくれる
・・・VBが内部的にがんばって変換する処理を行っている

2.文字列が簡単に扱える。
・・・VBが内部的に、領域確保やメモリ内のデータのコピーなどの処理をがんば...続きを読む

QVCのDLL内でmallocした構造体をVBで使用

題名通りですが、
VC側のDLLにてmallocで構造体の領域を確保しています。
この領域をVB側で使用したいのですが、やり方がわかりません。
イメージは
Public Declare Function GetData Lib "xxx.dll"
(ByRef datas As KOUZOUTAI, ByRef dataCnt As Long) As Boolean
みたいな形で、datasに構造体のデータ、及び
dataCntに領域確保したデータ数を取得出来ればなと思っております。
VB側では、これもイメージですが、

dim datas() as KOUZOUTAI
dim dataCnt as long

GetData(datas, dataCnt)
for cnt=0 to dataCnt - 1
msgbox datas(cnt).a
msgbox datas(cnt).b
msgbox datas(cnt).c
next

みたいな感じで処理をしたいと思っております。
お聞きしたい事は
1)そもそも可能なのか?
2)declare宣言のdatasのところが???です。
3)dim datas() as KOUZOUTAIのところも宣言が???です。
4)datas(cnt).a等としているところも配列?として処理出来るのかが???です。

以上、よろしくお願いします。

題名通りですが、
VC側のDLLにてmallocで構造体の領域を確保しています。
この領域をVB側で使用したいのですが、やり方がわかりません。
イメージは
Public Declare Function GetData Lib "xxx.dll"
(ByRef datas As KOUZOUTAI, ByRef dataCnt As Long) As Boolean
みたいな形で、datasに構造体のデータ、及び
dataCntに領域確保したデータ数を取得出来ればなと思っております。
VB側では、これもイメージですが、

dim datas() as KOUZOUTAI
dim dataCnt as long

GetData(datas, dataCnt)
for cnt...続きを読む

Aベストアンサー

>1)そもそも可能なのか?
VC側でVB配列を扱える人が作ったDLLなんでしょうか?
できるようならmallocは使わずSafeArray系APIを使うと思います。
最低でもVB側で解放できるようにGlobalAllocを使うはずです。
無理すれば可能だとは思いますが、一時的に成功してもガベージ
コレクションが起きた後で動作が不安定になるでしょう。

>2)declare宣言のdatasのところが???です。
VC側で SAFEARRAY **datas となっていれば datas() As KOUZOUTAIと
なります。そうすると、mallocではなく、SafeArrayCreateで確保
された領域のポインタが入らなくてはなりません。
VC側が struct xxx *p となっているならdatas As KOUZOUTAIです。

>3)dim datas() as KOUZOUTAIのところも宣言が???です。
Declarationの所では配列要素数を省略した定義は可能です。
後でReDim文で配列領域を確保します。配列要素数を定義すると
固定配列になるので、VC側でメモリを削除したり、確保したり
できません。

>4)datas(cnt).a等としているところも配列?として処理出来るのかが???です。
構造体の配列は使用可能です。書式も合っています。

どうしてもVC側で作ったものを使いたいならGlobalAllocでメモリを
確保し、これを戻り値(Long型)とします。VB側では必要な領域を
確保した後、RtlMoveMemoryで内容をコピーして使えば良いでしょう。
尚、VBの変数のポインタはVarPtr関数で求められます。

>1)そもそも可能なのか?
VC側でVB配列を扱える人が作ったDLLなんでしょうか?
できるようならmallocは使わずSafeArray系APIを使うと思います。
最低でもVB側で解放できるようにGlobalAllocを使うはずです。
無理すれば可能だとは思いますが、一時的に成功してもガベージ
コレクションが起きた後で動作が不安定になるでしょう。

>2)declare宣言のdatasのところが???です。
VC側で SAFEARRAY **datas となっていれば datas() As KOUZOUTAIと
なります。そうすると、mallocではなく、SafeArrayCrea...続きを読む


人気Q&Aランキング

おすすめ情報