Click here to Skip to main content
15,887,939 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
I tried posting this already but got no response. Maybe my post was too long and complex. I'll try again. I have a DLL that has a function being called from a C++ app. I want to also call that function from a vb.net app. THis is the function definition in the C++ app:

C#
typedef unsigned int (*DLL_SENDCOMMAND) (const char   *,
                                      const char   ,
                                      unsigned int ,
                                      int          ,
                                      int          ,
                                      int          ,
                                      const char   *,
                                      const char   *,
                                      const char   *,
                                      const char   *,
                                      char         *,
                                      int          );


This is the definition I am using in my vb.net app:

VB
Private Declare Function SendCommand Lib "STBremoteconfDLL.dll" Alias "?STBRemoteLib_SendCommand@@YAHPBDDIHHH0000PADH@Z" (ByVal cmd As String, ByVal TimeToLive As String, _
        ByRef Timeout As UInteger, ByVal CommandType As Integer, ByVal y2 As Integer, ByVal ConnectTimeOut As Integer, ByVal SaveFile As String, ByVal KeyFile As String, _
        ByVal KeyPhrase As String, ByVal x As String, ByRef str As String, ByVal z As Integer) As UInteger


Is there something wrong with my function declaration? I know the entry point is good. The function actually works, but it errors and doesn't give up the reply. I get that error about reading/writing to protected memory when I call it. Thanks.
Posted
Comments
Sergey Alexandrovich Kryukov 13-Mar-13 15:27pm    
Please don't re-post. If you need your previous question, please put it all on this page.
—SA

Have a look at: Using ACE with C++ CLI[^] - it's usually easier to use C++/CLI to bridge the gap between managed and unmanaged code.

Best regards
Espen Harlinn
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 25-Apr-13 18:59pm    
ACE again! A 5.
—SA
I can see just some type discrepancy. C++ int is be default marshaled as System.Int32, not UInteger (System.UInt32) which is like C++ unsigned int; more importantly, C++ char is a 8-bit char, it is marshaled as .NET byte.

—SA
 
Share this answer
 
v2
Comments
Matthew Faithfull 13-Mar-13 15:58pm    
(System.UInt16) for unsigned int?
I would have thought System.UInt32 but I'm no expert at C-.NET type equivalence.
Sergey Alexandrovich Kryukov 13-Mar-13 16:02pm    
This was my typo, of course, it is System.UInt32.
Thank you very much for your note.
—SA
To debug this you should really provide several "Hello World" interfaces (with and without parameters) and test that the process works as you intended, passing int, float, string and anything else of interest to your app. Then switch over to the other functions.

I don't think you are correctly verifying the inter-language handshake details.
 
Share this answer
 
Comments
REALJASONYOUNG 13-Mar-13 18:01pm    
I'm not sure that would be useful to me. I don't have access to the original source dll. That C++ function declaration is from a C++ app that is accessing the dll. We want to eliminate the C++ app and access the dll directly from a vb.net app.
Does this look better? I'm still getting the same error when calling it though. I included the code to actually call the function:

VB
Private Declare Function SendCommand Lib "STBremoteconfDLL.dll" Alias "?STBRemoteLib_SendCommand@@YAHPBDDIHHH0000PADH@Z" (ByVal cmd As String, ByVal TimeToLive As Byte, ByRef Timeout As UInteger, ByVal CommandType As Integer, ByVal y2 As Integer, ByVal ConnectTimeOut As Integer, ByVal SaveFile As String, ByVal KeyFile As String, ByVal KeyPhrase As String, ByVal x As String, ByRef str As String, ByVal z As Integer) As UInteger


VB
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim strKeyFile As String = "MYKEYFILE.key"
        Dim strPass As String = "mypassphrase"
        Dim y2 As String = ""
        Dim z As String = ""
        Dim strReply As String = ""
        Dim strCommand As String = "10.1.0.100 REBOOT"

        Try
            Dim i As UInteger = SendCommand("10.1.0.100 REBOOT", Convert.ToByte("200"), 100, 0, 0, 3, y2, strKeyFile, strPass, z, strReply, 65535)

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
 
Share this answer
 
Comments
Matthew Faithfull 13-Mar-13 16:07pm    
You're passing in .NET String instances by values to a function which takes char* parameters. I don't know if that can work but if so I don't know how unless the calling side knows somehow to convert object instance to an array of bytes and pass the address?
H.Brydon 13-Mar-13 17:03pm    
Don't post new details of your question as solutions or you might see a small downvote storm.
REALJASONYOUNG 13-Mar-13 17:04pm    
Allright. I thought that would be better than posting them in this small box. I'll remember that.
Allright. I changed the strings in the declaration to intptr. This is what I'm using to call the function. The function is still working but it's still giving me that memory error and not giving me the return value.

VB
Dim pCommand As IntPtr
        pCommand = Marshal.StringToCoTaskMemAnsi("10.1.0.100 REBOOT")
        Dim encodedBytes As Byte() = Encoding.UTF8.GetBytes("10.1.0.100 REBOOT")
        Marshal.Copy(encodedBytes, 0, pCommand, encodedBytes.Length)

        Dim pReply As New IntPtr
        pReply = Marshal.StringToCoTaskMemAnsi("")
        Dim encodedBytes2 As Byte() = Encoding.UTF8.GetBytes("")
        Marshal.Copy(encodedBytes2, 0, pReply, encodedBytes2.Length)

        Dim pSaveFile As IntPtr
        pSaveFile = Marshal.StringToCoTaskMemAnsi("")
        Dim encodedBytes3 As Byte() = Encoding.UTF8.GetBytes("")
        Marshal.Copy(encodedBytes3, 0, pSaveFile, encodedBytes3.Length)

        Dim pKeyFile As New IntPtr
        pKeyFile = Marshal.StringToCoTaskMemAnsi(strKeyFile)
        Dim encodedBytes4 As Byte() = Encoding.UTF8.GetBytes(strKeyFile)
        Marshal.Copy(encodedBytes4, 0, pKeyFile, encodedBytes4.Length)

        Dim pKeyPhrase As IntPtr
        pKeyPhrase = Marshal.StringToCoTaskMemAnsi(strPass)
        Dim encodedBytes5 As Byte() = Encoding.UTF8.GetBytes(strPass)
        Marshal.Copy(encodedBytes5, 0, pKeyPhrase, encodedBytes5.Length)

        Dim px As New IntPtr
        px = Marshal.StringToCoTaskMemAnsi("")
        Dim encodedBytes6 As Byte() = Encoding.UTF8.GetBytes("")
        Marshal.Copy(encodedBytes6, 0, px, encodedBytes6.Length)

        Try
            Dim i As String = SendCommand(pCommand, Convert.ToByte("200"), 100, 0, 0, 3, px, pKeyFile, pKeyPhrase, px, pReply, 65535)

            MsgBox("good")
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900