Link to home
Start Free TrialLog in
Avatar of diane903
diane903Flag for United States of America

asked on

Using a DLL in VB

I am new to using DLLs in Vb and am having a problem accessing a DLL function.  I have a DLL with the following IDL file:

//**********************************
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: prxySayHi.DLL
[  uuid(1D5A64A8-6705-4156-B4B6-0354E3A96A3F),  version(1.0)]
library prxySayHi
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");
    // Forward declare all types defined in this typelib
    dispinterface _intfcSayHi;
    [
      uuid(2D02AD08-4CB8-4857-8CAB-85828BFC8CFD),
      helpstring("Generated on Tuesday, March 20, 2007 03:43:39 PM")
    ]
    dispinterface _intfcSayHi {
        properties:
        methods:
            [id(0x00000001)]
            long methdSayHi(
                            [in, out,
                custom({F0D491D0-0DF9-4ECA-AFB0-5C573ABE9325}, "100")            
           
] BSTR* vDataBuf,
                            [out,
                custom({F0D491D0-0DF9-4ECA-AFB0-5C573ABE9325}, "0")            
           
] long* tpurcode);
    };
    [
      uuid(2E2E8AFE-DEBD-4C51-952C-105C89C98627),
      appobject
    ]
    coclass intfcSayHi {
        [default] dispinterface _intfcSayHi;
    };
};
//**********************************
The purpose of the DLL is just to pass a "Hello" message back to the calling program.

I am using VB 2005 Express to write the calling program.  I have creaded a button to execute the call and a text field to display the "Hello" response.
When I view the dll in the object browser, I see two options available: prxySayHi.intfcSayHi and prxySayHi._intfcSayHi both showing my methdSayHi with appropriate variables.

If i call it using  prxySayHi.intfcSayHi I get the following error:
'Unable to cast COM object of type 'prxySayHi.intfcSayHiClass' to interface type 'prxySayHi._intfcSayHi'. This operation failed because the QueryInterface call on the COM component for the interface with IID  "
This is the code I'm using:
'**********************-Start-***************************
Public Class GetHi
    Private Sub cmdGetHello_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdGetHello.Click
        Dim intRetVal As Integer
        Dim strDataBuf As String
        Dim intUrCode As Int32
        Dim objCSayHi As prxySayHi.intfcSayHi
        objCSayHi = New prxySayHi.intfcSayHi
        strDataBuf = "Hi"
        intRetVal = objCSayHi.methdSayHi(strDataBuf, intUrCode)
        Me.txtHelloMsg.Text = strDataBuf
    End Sub
End Class
'**********************-End-***************************

If I try to use the interface type 'prxySayHi._intfcSayHi' usning the following code I get other errors.

'**********************-Start-***************************
Public Class GetHi
    Private Sub cmdGetHello_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdGetHello.Click
        Dim intRetVal As Integer
        Dim strDataBuf As String
        Dim intUrCode As Int32
        Dim objISayHi As prxySayHi._intfcSayHi
        objISayHi = New prxySayHi._intfcSayHi
        strDataBuf = "Hi"
        intRetVal = objISayHi.methdSayHi(strDataBuf, intUrCode)
        Me.txtHelloMsg.Text = strDataBuf
    End Sub
End Class
'**********************-End-***************************
With this code on the 'objISayHi = New prxySayHi._intfcSayHi" line I get an error : "'New' cannot be used on an interface.      "
If I remove this line I get the following warning: "Variable 'objISayHi' is used before it has been assigned a value. A null reference exception could result at runtime."
If I ignore the warning and run the app I get - amazingly - a "NullReferenceException was unhandled" error.

I know I must be donig something stupid but I'm missing it.  Any suggestions???

Thanks,  Diane

Avatar of VBRocks
VBRocks
Flag of United States of America image

Did you make the dll in VB.NET using ComInterop?  (a "tlb" is a TypeLibrary used with COM - VB6, etc) If you are making the dll in VB.NET to work with a .NET application, then you don't have to use ComInterop, so uncheck it in the Project Properties, if you have it checked.  That way it will only create a "dll", which you will be able to add as a reference and instantiate using the "New" keyword.

Hope that helps.
Just another comment:  Although you can create a dll/tlb in .NET using ComInterop for backwards compatibility with VB6, etc., you cannot use this dll with a .NET application, which may be why you are getting the error.  If you create the dll without using ComInterop, then it should work fine with your .NET application.

Avatar of diane903

ASKER

The dll is created by a proprietary development environment that provides linkage to an application my company wants to use.  We have no visibility into the dll other than the idl file.  We can specify the method parameters and return values but other than that we have no control over the coding of the dll.  It's all done internal to their environment and includes code that links into their proprietary appplication.  Regardless, I should be able to get to the DLL and I'm not even getting to that point.
Just one more comment:  When you create your dll to work with .NET, do not add a "Com Class", but just add a regular "Class".

Ok.  I guess I don't know then.  Sorry.
Please close this.  I found a solution myself
The better and more intuitive way for using a COM dll is via VC++ or VB 6.

In addition, all errors you have received have something to do with the COM interface not being able to create the class object (QueryInterface is a method that has to be implements whenever an IUnknown object is implemented, which is the case for all COM objects).

Possible reasons include the following:

1. Incorrect settings in your IDE / incorrect project settings.
2. Internal problem with the COM dll.
3. Registry problem (the COM dll is fine but is not properly registered)
4. Dependency problem - the COM dll requires some intermediate libraries which are not available (or are not up-to-date) on the target machine  (all dlls created b y VB6, for example, require that the target machine has an updated version of msvbvm60.dll)
Avatar of wish756
wish756

diane903,

Could you please post the solution too for the benefit of others looking at this discussion.

Thank You.
The solution is as follows:
1. make sure the dll is registered.  OLE View is a good check.
2. Add the dll as a reference.

Following is similar to the code I used for the button click.   The ouput "Hello" comes from the dll in vDataBuf and is displayed  in a text box txtHi.  The tpurcode is return code used by the program that generates the dll.

        Dim tpurcode As Integer
        Dim objGetData As Object
        Dim strHi As String = ""

        Try
            objGetData = CreateObject("prxySayHi.intfcSayHi.1")
            Call objGetData.methdSayHi(strHi, tpurcode)
        Catch ex As Exception When ex.Message = "Cannot create ActiveX component."
            strHi = "DLL Failure"
        Catch ex As Exception
            MsgBox("Err: " & ex.Message)
        End Try
        If Len(strHi) > 1 Then
            Me.txtHi.Text = strHi
        Else
            Me.txtHi.Text = "Error!"
        End If
ASKER CERTIFIED SOLUTION
Avatar of Computer101
Computer101
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial