C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: ActiveX DLLへIntPtrが正しく渡せない


(過去ログ 115 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■67808 / inTopicNo.1)  ActiveX DLLへIntPtrが正しく渡せない
  
□投稿者/ アブサン (1回)-(2013/09/03(Tue) 16:40:16)

分類:[ASP.NET (C#)] 

こんにちは。

ASP.Net(C#)から自作ActiveX DLLへ文字列の受け渡しを行おう
としていますが、「Marshal.AllocHGlobal」で取得したIntPtrの値が
正しく渡せない状態にあります。64bit環境です。

下記はソースを抜粋したものですが、ASP.Netで表示しているアドレス値
とActiveX側でファイルに出力しているアドレス値が一致しません。

ASP.Netで「Marshal.AllocHGlobal」ではなく、Bitmapから取得した
Graphics.GetHdc()で取得したIntPtrの場合はアドレス値が一致します。

なぜGraphics.GetHdc()で確認したかというと、ActiveXの別メソッドで
Graphics.GetHdc()のIntPtrを引数にしていますが、そちらは問題なく
動作していたためです。

下記ソースで問題あるようでしたらご指摘をお願いします。
また、注意点などありましたらお願いします。

-----------------------------------------------------------------------------------------
(ActiveX DLL)VC++側

BEGIN_DISPATCH_MAP(CTest, CCmdTarget)
    DISP_FUNCTION_ID(CTest, "GetTest", dispidGetTest, GetTest, VT_I4, VTS_VARIANT)
END_DISPATCH_MAP()

LONG CTest::GetTest(VARIANT data)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    debug((ULONGLONG)data.pvarVal);
    return 0;
}

void CTest::debug(ULONGLONG v)
{
    FILE *f;
    char msg[256];
    
    sprintf(msg, "%lld\n", v);
    f = fopen("C:\\temp\\debug.txt", "a"); 
    fprintf(f, msg);
    fclose(f);
}

-----------------------------------------------------------------------------------------
(ASP.Net C#)呼び出し側

[ComImport, Guid("xxxx")]
public class Test
{
}

[Guid("xxxx"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ITest
{
    Int32 GetTest(
        [In, Out, MarshalAs(UnmanagedType.SysInt)] IntPtr data);
}

protected void Page_Load(object sender, EventArgs e)
{
    ITest test = (ITest)new Test();
    IntPtr hData = Marshal.AllocHGlobal(500);
    try
    {
        div_test.InnerHtml = ((UInt64)hData.ToInt64()).ToString();
        test.GetTest(hData);
    }
    finally
    {
        Marshal.FreeHGlobal(hData);
    }
}

引用返信 編集キー/
■67809 / inTopicNo.2)  Re[1]: ActiveX DLLへIntPtrが正しく渡せない
□投稿者/ Hongliang (90回)-(2013/09/03(Tue) 16:55:00)
VARIANTってポインタじゃないですけど。渡ってきた8バイトの値をむりやり構造体メンバに割り当てて読もうとしても、そりゃ正しく読めるわけありません。
文字列の受け渡しなら普通はBSTR使うもんじゃないですか?(ActiveX DLLは余り詳しくないですが)
引用返信 編集キー/
■67810 / inTopicNo.3)  Re[2]: ActiveX DLLへIntPtrが正しく渡せない
□投稿者/ アブサン (2回)-(2013/09/03(Tue) 17:32:10)
Hongliang さん、ご返信ありがとうございます。

え〜と、おっしゃる通りだと思います。
最初は StringBuilder → BSTR でやろうとしたのですが
実行時エラーで型が違うとか言われてNGでした。

その時は下記で行っていました。
Int32 GetTest([In, Out, MarshalAs(UnmanagedType.BSTR)] StringBuilder data);

因みに下記は問題なく渡せるのですが、Stringでは返すことができないので…
Int32 GetTest([In, MarshalAs(UnmanagedType.BSTR)] String data);

そこでGraphics.GetHdc()→VARIANTで動作していたのがあったため
無理やり当てはめてみた次第です。

通常使用する型が何なのかがわからない状態です。
引き続き、よろしくお願いします。

引用返信 編集キー/
■67811 / inTopicNo.4)  Re[3]: ActiveX DLLへIntPtrが正しく渡せない
□投稿者/ Hongliang (91回)-(2013/09/03(Tue) 17:45:32)
BSTRを使うなら、文字列を受け取るC#側は
int GetTest([MarshalAs(UnmanagedType.BStr)] out string value);
になるはずです。
文字列を与えるC++側は、SysAllocString(またはそれに該当する処理)の結果を、引数BSTR*のポイント先に代入する形になるでしょう。

StringBuilderは呼び出し側が文字列領域を割り当てておいて呼び出し先にコピーさせるために使用されるものであり、常に文字列を用意する側が領域を確保するBSTRとは噛み合いません。
引用返信 編集キー/
■67812 / inTopicNo.5)  Re[4]: ActiveX DLLへIntPtrが正しく渡せない
□投稿者/ アブサン (3回)-(2013/09/03(Tue) 18:04:57)
Hongliang さん、ご返信ありがとうございます。
教えていただいた方法で試してみます。

引用返信 編集キー/
■67815 / inTopicNo.6)  Re[4]: ActiveX DLLへIntPtrが正しく渡せない
□投稿者/ アブサン (4回)-(2013/09/03(Tue) 19:39:10)
Hongliang さん

教えていただいた方法でできました。
ありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -