diane903
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-B4 B6-0354E3A 96A3F), version(1.0)]
library prxySayHi
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-0 0000000004 6}
importlib("stdole2.tlb");
// Forward declare all types defined in this typelib
dispinterface _intfcSayHi;
[
uuid(2D02AD08-4CB8-4857-8C AB-85828BF C8CFD),
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-5C57 3ABE9325}, "100")
] BSTR* vDataBuf,
[out,
custom({F0D491D0-0DF9-4ECA -AFB0-5C57 3ABE9325}, "0")
] long* tpurcode);
};
[
uuid(2E2E8AFE-DEBD-4C51-95 2C-105C89C 98627),
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:
'**********************-St art-****** ********** ********** *
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(strDa taBuf, intUrCode)
Me.txtHelloMsg.Text = strDataBuf
End Sub
End Class
'**********************-En d-******** ********** *********
If I try to use the interface type 'prxySayHi._intfcSayHi' usning the following code I get other errors.
'**********************-St art-****** ********** ********** *
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(strDa taBuf, intUrCode)
Me.txtHelloMsg.Text = strDataBuf
End Sub
End Class
'**********************-En d-******** ********** *********
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
//************************
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: prxySayHi.DLL
[ uuid(1D5A64A8-6705-4156-B4
library prxySayHi
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-0
importlib("stdole2.tlb");
// Forward declare all types defined in this typelib
dispinterface _intfcSayHi;
[
uuid(2D02AD08-4CB8-4857-8C
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
] BSTR* vDataBuf,
[out,
custom({F0D491D0-0DF9-4ECA
] long* tpurcode);
};
[
uuid(2E2E8AFE-DEBD-4C51-95
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
This is the code I'm using:
'**********************-St
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(strDa
Me.txtHelloMsg.Text = strDataBuf
End Sub
End Class
'**********************-En
If I try to use the interface type 'prxySayHi._intfcSayHi' usning the following code I get other errors.
'**********************-St
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(strDa
Me.txtHelloMsg.Text = strDataBuf
End Sub
End Class
'**********************-En
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
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.
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.
ASKER
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)
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)
diane903,
Could you please post the solution too for the benefit of others looking at this discussion.
Thank You.
Could you please post the solution too for the benefit of others looking at this discussion.
Thank You.
ASKER
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.in tfcSayHi.1 ")
Call objGetData.methdSayHi(strH i, 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
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.in
Call objGetData.methdSayHi(strH
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hope that helps.