I am trying to pass a filename from and executable to a dll and I get the error listed in the title. Any thoughts on how to correct this?
Printable View
I am trying to pass a filename from and executable to a dll and I get the error listed in the title. Any thoughts on how to correct this?
Post the Key code that you are using then we can see to it.??
The actuall dll code is rather long, but the calling routine is as follows
Private Declare Sub ParseBDF Lib _
"C:\MyDllLibrary\BDF Parser\BDFParserDLL.dll" _
(ByVal FName As String) ', ByRef Gctr As Integer)
Sub Main()
Dim FName As String
If Command$ <> "" Then
FName = Command$
Else
With Form1.CD1
.FileName = ""
.CancelError = True
.DialogTitle = "Select BDF File"
.Filter = "Bulk Data File (*.bdf)|*.bdf|All Files (*.*)|*.*"
.Flags = cdlOFNFileMustExist Or cdlOFNExplorer Or cdlOFNLongNames
.ShowOpen
FName = .FileName
End With
End If
MsgBox (FName)
ParseBDF FName ', Gctr)
Stop
End Sub
The dll starts as follows
Sub ParseBDF(ByVal FName As String) ', ByRef Gctr As Integer)
Dim FNum As Integer: FNum = FreeFile
Dim TStr As String
Dim tmpstr As String
Dim tmplen1 As Integer
Dim tmplen2 As Integer
Dim comlen1 As Integer
Dim comlen2 As Integer
Dim FileType As String * 3
Dim LineType As String
Erase Grid
Gctr = 0: Pctr = 0: Mctr = 0
Close FNum
Open FName For Input As FNum
Line Input #FNum, TStr
...
End Sub
By going through this part of the code
in the DLL part, How can you close anything that has not been opened yet.Code:Erase Grid
Gctr = 0: Pctr = 0: Mctr = 0
Close FNum
Open FName For Input As FNum
Line Input #FNum, TStr
Before closing the File, you need to open it. And your function doesn't open anything prior to Close FNum statement.
try doing this instead.
Code:Erase Grid
Gctr = 0: Pctr = 0: Mctr = 0
Open FName For Input As FNum
Line Input #FNum, TStr
...
Close FNum
Ok Looks like the problem is in the dll..
Freefile will give you the next available free file number .. Closing this file number may be causing your problem..Code:Sub ParseBDF(ByVal FName As String) ', ByRef Gctr As Integer)
Dim FNum As Integer: FNum = FreeFile
Dim TStr As String
Dim tmpstr As String
Dim tmplen1 As Integer
Dim tmplen2 As Integer
Dim comlen1 As Integer
Dim comlen2 As Integer
Dim FileType As String * 3
Dim LineType As String
Erase Grid
Gctr = 0: Pctr = 0: Mctr = 0
Close FNum <----------------------- REMOVE THIS LINE
Open FName For Input As FNum
Line Input #FNum, TStr
...
CLOSE FNUM <----------------------- Place it here..
End Sub
Quicker on the draw i see... :)Quote:
Originally Posted by vb_the_best
Actually, the close FNum statement is not the culprit. I added a message box after that line to see what FName is, and it comes up ?????????. However, just before calling the dll I have teh same message box and FName is correct. Any thoughts?
In the main calling code I changed the line from
ParseBDF FName
to
ParseBDF StrConv(FName, vbUniCode)
checking FName in the dll gives the correct filename for FName.
One last question...
Is there a way to debug or step through dlls at runtime?
Ok instead of trying to explain here just follow this tread also in this forum
http://www.codeguru.com/forum/showthread.php?t=357076
I think it should help you...
Well i wrote a small program and it seems Close statement in the above posted code will not give this error. There seems to be some other problem.
Not sure if you can step through the DLL. As your function (in the DLL) is not a big one, you can put simple Message Boxes after each statement and then you will be able to know which statement is actually erroring out.
slaphap,
I don't know what tool you used to create the DLL you have (I saw one tool before for compiling VB apps with functions into EAT like C++) but I think you should consider a way to avoid converting from UNICODE to ANSI and vise versa. It may confuse you and might give you more error as you go on with your project.
With the "Declare" keyword, VB converts strings from UNICODE to ANSI every time we enter the function and converts back the string (now from ANSI) to UNICODE. This would be confusing sometimes and might be hard to find where the error is. To avoid these translations, I could suggest you 2 options.
1. The first and easiest way is to make this DLL, an activeX dll. With this, you'll make sure that they are compatible as to transferring strings from the EXE to the DLL and back.
2. Second, you can make a type library (.TLB) for the DLL functions using the MIDL compiler. By doing this, you can tell VB that it should not translate the string and pass it as is into the function. Here's a sample for you dll functionsave it into BDFParserDLL.idl and then compile it with commandCode:[
uuid(DD1853C1-B67B-11d6-AC3B-00001CDF360C),
helpstring("BDFParserDLL IDL for VB")
]
library BDFParserDLL_Lib
{
[dllname("BDFParserDLL.DLL")] // the dll name
module BDFParserDLL {
[entry("ParseBDF")] void ParseBDF(BSTR FName); // function name in entry()
// and use BSTR to tell VB it's String
}
}
Add the generated .TLB to your References and use the function without conversion concerns. This TLB will be used only for development, you don't need to distribute it with the EXE.Code:MIDL BDFParserDLL.idl
When you run it, place the DLL in a location that the EXE can see it, (EG. Windows folder or on the EXE folder).
Hope it would be of help to you.
Thanks for the help rxbagain. The problem is that this will be used with other source code other than VB and have been edicted to not use activeXdlls. I think I am getting a better grasp on things now. I do have a couple of questions more though..
1. Is there a way to step through a dll for debugging purposes?
2. Are Type declarations allowed in dlls? eg
public type xxx
x as integer
y as single
end type
userstuff(x,x) as xxx
Any help will be appreciated
I using the same code provided and can run in Excel 2007.
But when I run it in Excel 2003 & XP, error encountered.
compile error:
Wrong number of argument of invalid property assignment.
and it highlighted the on: InsertPictureInRange
The code is as shown below:
Sub TestInsertPictureInRange()
InsertPictureInRange "\\semsv003\d\LF Photo\" & Range("MENU!$E$3") & ".jpg", _
Range("CUTTING!$A77:$Z95")
End Sub
Sub InsertPictureInRange(PictureFileName As String, TargetCells As Range)
' inserts a picture and resizes it to fit the TargetCells range
Dim p As Object, t As Double, l As Double, w As Double, h As Double
Sheets("CUTTING").Select
If TypeName(ActiveSheet) <> "Worksheet" Then Exit Sub
If Dir(PictureFileName) = "" Then Exit Sub
' import picture
Set p = ActiveSheet.Pictures.Insert(PictureFileName)
' determine positions
With TargetCells
t = .Top
l = .Left
w = .Offset(0, .Columns.Count).Left - .Left
h = .Offset(.Rows.Count, 0).Top - .Top
End With
' position picture
With p
.Top = t
.Left = l
.Width = w
.Height = h
End With
Set p = Nothing
' ********************************************************
End Sub
Please advice.
thank you.
Please go back and reformat your code. Use CODE TAGS, and also include the connection information that you are using. You need to use 'late-binding' so that you can use any version of a product.
Code:Option Explicit
' These are both examples of Late Binding
Public Sub RunAccessMacro(strDB As String, strMacro As String)
'================================================================
'for late binding declare it As Object and use CreateObject() function
Dim AccessDB As Object
Set AccessDB = CreateObject("Access.Application")
With AccessDB
.OpenCurrentDatabase strDB
.DoCmd.RunMacro strMacro, 1
'.Visible = True 'you decide
.CloseCurrentDatabase
End With
Set AccessDB = Nothing
End Sub
Public Sub ExcelMacro()
Dim excl As Object
Dim wrbk As Object
Set excl = CreateObject("Excel.Application")
excl.DisplayAlerts = False
Set wrbk = excl.Workbooks.Open("myfile", , True, , "mypassword")
excl.Run "MacroName", "arg1", "arg2"
End Sub