System.IntPtr に変換できません への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 JUNKOU  (社会人) 投稿日時 2009/11/29 11:08:24
魔界の仮面弁士 様 ありがとうございます。

下記のように変更したら、うまく行きました。
たいへんお世話になりました。

又、お世話になるかと思いますのでよろしくお願いします。

        Dim MyCall As New TessCall

        Dim CallA As CallAA = New CallAA(AddressOf MyCall.glVertex3dvCB)
        Dim CallB As CallBB = New CallBB(AddressOf MyCall.glBeginCB)
        Dim CallC As CallCC = New CallCC(AddressOf MyCall.glEndCB)
        Dim CallD As CallDD = New CallDD(AddressOf MyCall.glErrorCB)

        Dim returnValue1 As IntPtr
        Dim returnValue2 As IntPtr
        Dim returnValue3 As IntPtr
        Dim returnValue4 As IntPtr

        returnValue1 = Marshal.GetFunctionPointerForDelegate(CallA)
        returnValue2 = Marshal.GetFunctionPointerForDelegate(CallB)
        returnValue3 = Marshal.GetFunctionPointerForDelegate(CallC)
        returnValue4 = Marshal.GetFunctionPointerForDelegate(CallD)

        tobj = gluNewTess()

        gluTessCallback(tobj, GLU_TESS_VERTEX, returnValue1) ' AddressOf glVertex3dvCB) 
        gluTessCallback(tobj, GLU_TESS_BEGIN, returnValue2)  ' AddressOf glBeginCB) 
        gluTessCallback(tobj, GLU_TESS_END, returnValue3)    ' AddressOf glEndCB) 
        gluTessCallback(tobj, GLU_TESS_ERROR, returnValue4)  ' AddressOf glErrorCB) 

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/11/28 18:47:42
ざっと見たところ、.NET の文法という話以前に、ロジック段階で不備があるように見えます。


では、GLU_TESS_VERTEX を指定して、glVertex3dvCB をコールバックさせ、
また、GLU_TESS_END を指定して、glEndCB をコールバックさせていたのですよね。
gluTessCallback tobj, GLU_TESS_VERTEX, AddressOf glVertex3dvCB
gluTessCallback tobj, GLU_TESS_BEGIN, AddressOf glBeginCB
gluTessCallback tobj, GLU_TESS_END, AddressOf glEndCB

 

しかし、の方では、GLU_TESS_VERTEX にて glEndCB をコールバックさせようとしています。
glVertex3dvCB と glEndCB では、メソッドの意味も引数定義も違っているでしょうから、
この指定方法では VB2008 どころか、VB6 であってもうまくいかないと思いますよ。
Dim CallC As New CallCC(AddressOf MyCall.glEndCB)
Dim returnValue3 As IntPtr = Marshal.GetFunctionPointerForDelegate(CallC)
gluTessCallback(tobj, GLU_TESS_VERTEX, returnValue3)

 

VB2008 に移植する前に、gluTessCallback に指定するそれぞれの引数の意味について、
もう一度調べてみてください(コードの意味を理解してからの方が、移植作業が捗るかと思います)。
投稿者 (削除されました)  () 投稿日時 2009/11/28 18:46:35
(削除されました)
投稿者 (削除されました)  () 投稿日時 2009/11/28 18:08:17
(削除されました)
投稿者 (削除されました)  () 投稿日時 2009/11/28 07:50:19
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/11/28 06:12:18
# OpenGL は専門外なので、あまり具体的な回答はできないのですが。


> Public Class TessCall
>  Public Sub glEndCB()
>   glEnd()
>  End Sub
> End Class
これって、本当に GLU_TESS_VERTEX で使うためのメソッドですか?
End というからには、GLU_TESS_END で使う物にも見えるのですが…。


>  Public Delegate Sub CallCC() 'glEndCB()  'デリゲート 
引数無しの Sub なら、自身で Delegate を定義する代わりに、
MethodInvoker デリゲートをそのまま使う事もできます。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.methodinvoker.aspx


> Public Function TessMake(ByVal ListNo As Integer) As Integer
引数 ListNo が使われていないのが気になります。


>  gluTessCallback(tobj, GLU_TESS_VERTEX, returnValue3)
今回、gluTessCallback の引数は、Declare にて
 ByVal IntPtr
 ByVal UInt32
 ByVal IntPtr
と定義されているのですよね。しかし、ここで渡している引数はそれぞれ
 Dim tobj As Integer = gluNewTess()
 GLU_TESS_VERTEX …… 記載が無いので不明
 Dim returnValue3 As IntPtr = Marshal.GetFunctionPointerForDelegate(New CallCC(AddressOf MyCall.glEndCB))
となっており、少なくとも、第一引数の型が違っているように見えます。
それぞれに渡す値の型は、Declare 宣言と合わせておいてください。



> Public Declare Sub gluTessCallback Lib "GLU32.DLL" (ByVal tess As IntPtr, _
>                             ByVal which As UInt32, ByVal fn As IntPtr)
宣言部に
 Public Declare Sub gluTessCallback Lib "GLU32.DLL" (ByVal tess As IntPtr, _
                          ByVal which As UInt32, ByVal fn As MethodInvoker)
を追加すれば、
 Dim tessellate As IntPtr = gluNewTess()
 gluTessCallback(tobj, GLU_TESS_VERTEX, AddressOf glEndCB)
と記述できるかと思います。動くかどうかは別として。



> CallCC のアドレスが渡ってないようです。
そもそも、GLU_TESS_VERTEX のコールバック関数は、
引数 0 個の Sub メソッドではなく、
引数 1 個の Sub メソッドではありませんでしたっけ?

(GLU_TESS_END のコールバック関数は引数 0 個)
投稿者 JUNKOU  (社会人) 投稿日時 2009/11/28 04:27:16
葉月 様 ありがとうございます。

>gluTessCallback(tobj, GLU_TESS_VERTEX, Call1)
>Call1ではなく、Call11ではないでしょうか?
>コンパイルエラーの内容をヘルプで調べるのをお勧めします。

早速コードを書換えましたが、瞬間に
エラー 'Call11' は型です。有効な式ではありません。 
が表示しました。

    ありがとうございました。

又、ご教授をお願いします。
投稿者 葉月  (社会人) 投稿日時 2009/11/28 04:06:28
初めましてよろしくお願いします。
コードを追っかけた訳ではないので違うかも知れませんが――

gluTessCallback(tobj, GLU_TESS_VERTEX, Call1)
Call1ではなく、Call11ではないでしょうか?
コンパイルエラーの内容をヘルプで調べるのをお勧めします。
投稿者 JUNKOU  (社会人) 投稿日時 2009/11/28 02:33:07
YuO 様 と 魔界の仮面弁士 様 早速のご返信ありがとうございます。

下記'③では、CallCC のアドレスが渡ってないようです。
    '①と'② は正しく Public Sub glEndCB() へ行きます。
再度、申し訳ありませんが教えて下さい


Imports OpenGLLib
Imports System.Runtime.InteropServices

Public Class TessCall
    Public Sub glEndCB()
        glEnd()
    End Sub
End Class

Module DeclareB
    Public Delegate Sub CallCC() 'glEndCB()  'デリゲート 
End Module

Public Function TessMake(ByVal ListNo As IntegerAs Integer

        Dim tobj As Integer
        Dim MyCall As New TessCall
        Dim CallC As New CallCC(AddressOf MyCall.glEndCB)

        Dim returnValue3 As IntPtr

        returnValue3 = Marshal.GetFunctionPointerForDelegate(CallC)

        '① MainForm.Invoke(New CallCC(AddressOf MyCall.glEndCB)) 
        '② CallC() 
     
        tobj = gluNewTess()
        gluTessCallback(tobj, GLU_TESS_VERTEX, returnValue3) '③ 
                                              '~~~~~~~~~~~~ 
'尚、Imports OpenGLLib 内では 
Public Declare Sub gluTessCallback Lib "GLU32.DLL" (ByVal tess As IntPtr, _
                              ByVal which As UInt32, ByVal fn As IntPtr)
'です。 

 
VB.NET は理解するまでは、かなり時間が掛かりそうですね
  皆さんよろしくご教授をお願いします。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/11/27 21:08:30
Declare 宣言を、fn As IntPtr ではなく、fn As Call11 にしてみては如何でしょうか。
投稿者 YuO  (社会人) 投稿日時 2009/11/27 11:16:41
Marshal.GetFunctionPointerForDelegateを使って,デリゲートを関数ポインタに変換できます。
これを使うのがよいかと思います。
MSDN: Marshal.GetFunctionPointerForDelegate メソッド (System.Runtime.InteropServices)
http://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.marshal.getfunctionpointerfordelegate.aspx
投稿者 JUNKOU  (社会人) 投稿日時 2009/11/27 10:45:26
はじめまして
VB6 から VB2008 へ移植をしております。
'System.IntPtr' に変換できません のエラーで
困っております。
申し訳ありませんが教えて下さい

Imports OpenGLLib
Public Class TessCall
    Public Sub glVertex3dvCB(ByRef arg As Double)
        glVertex3dv(arg)
    End Sub
End Class

Module DeclareB
    Public Delegate Sub Call11(ByRef arg As Double)'デリゲート型 
End Module

Public Function TessMake(ByVal ListNo As IntegerAs Integer

        Dim tobj As Integer
        Dim MyCall As New TessCall
        Dim Call1 As Call11
        
        Call1 = New Call11(AddressOf MyCall.glVertex3dvCB)
     
        tobj = gluNewTess()
        gluTessCallback(tobj, GLU_TESS_VERTEX, Call1)
                                              '~~~~~ 
'尚、Imports OpenGLLib 内では 
Public Declare Sub gluTessCallback Lib "GLU32.DLL" (ByVal tess As IntPtr, _
                              ByVal which As UInt32, ByVal fn As IntPtr)
'です。 

                                              
        Call1 の値を 'System.IntPtr' に変換できません
        のエラーがでます。
    対処法を教えて頂けないでしょうか