how to create a function called from an exe?

K

Keith G Hicks

I'm an experienced foxpro, vba, delphi, sql programmer but this is something
new to me. I'm creating a pretty simple vb.net exe (scantextfiles.exe) that
will run on a server and read some text files into a database. But I also
need to create a stand alone function that can be called by
scantextfiles.exe. This stand alone function will use the MeasureString
method to get the length of some of the text in the text files. I'm not
putting that function in scantextfiles.exe because I need to call it from a
couple other places as well. So I'm thinking this needs to be a dll that I
can just plop into a folder somewhere. But I have really no idea how to do
that. I've never created a dll before. I'm not sure that's the best way to
go anyway. To make things a little more complicated (maybe) I'm using vb
2005 express to do all of this.

I created a test dll project and my class1.vb code is as follows (just to
try all this out):

Imports System.Math

Public Class Class1

Private Function fncSqRt(ByVal inputval As Double) As Double

If inputval < 0 Then
Return -1
Else
Return Sqrt(inputval)
End If

End Function

End Class

I compiled the dll and so I have TestDLL.dll sitting in my release folder.

Ok, so now what? :) I really am not sure if I'm headed in the right
direction. I'm also not sure how to call the dll from scantextfiles.exe. I
know a lot of this is going to sound pretty basic but like I said, this is a
new area to me. Any help or pionting me in the right direction would be
appreciated.

TIA,

Keith
 
P

Phill W.

Keith said:
I'm creating a pretty simple vb.net exe (scantextfiles.exe) that
will run on a server and read some text files into a database.

You might have to consider writing it as a Windows Service unless you
can guarantee that you can run your program on the server's console.
Luckily, that's not such a Big Deal as it used to be.
I also need to create a stand alone function that can be called by
scantextfiles.exe. This stand alone function will use the MeasureString
method to get the length of some of the text in the text files. I'm not
putting that function in scantextfiles.exe because I need to call it from a
couple other places as well. So I'm thinking this needs to be a dll that I
can just plop into a folder somewhere.

That's the easiest way to reuse it, as it's loaded and executed at
run-time. However, you can still "share" code between projects by
"linking" the source files from one project into one or more /other/
projects (although, to be honest, building the shared stuff into a dll
/is/ probably easier to manage, in the long run).
But I have really no idea how to do that.
I've never created a dll before.

Reading ahead, I think you /have/. :)
I created a test dll project and my class1.vb code is as follows (just to
try all this out):

Public Class Class1
/Public/ Function fncSqRt(ByVal inputval As Double) As Double
. . .
End Function
End Class

Your .exe project will only be able to see things that are Public in
your dll project (to start with, anyway).
I compiled the dll and so I have TestDLL.dll sitting in my release folder.

See? You /have/ built a dll.
Ok, so now what? :) I really am not sure if I'm headed in the right
direction.

So far, so good.
I'm also not sure how to call the dll from scantextfiles.exe.

From your .exe project, add a Reference to the dll you've compiled
(you'll have to Browse to it). Don't be surprised when a copy of this
dll "magically" appears alongside your .exe - that's how Visual Studio
handles this.

Next, in your .exe project code, create an instance of your class

Private Sub Button1_Click( ... ) _
Handles Button1.Click

Dim c1 as New Class1
Dim d2 as Double = c1.fncSqRt( 99 )

DirectCast( sender, Button ).Text _
= d2.ToString( "0.000" )

End Sub

There's loads more that /can/ be done as you go forward with this
("fixing" the Assembly Version, putting the "shared" assembly into the
Global Assembly Cache, and so on), but that should get you started.

HTH,
Phill W.
 
K

kimiraikkonen

I'm an experienced foxpro, vba, delphi, sql programmer but this is something
new to me. I'm creating a pretty simple vb.net exe (scantextfiles.exe) that
will run on a server and read some text files into a database. But I also
need to create a stand alone function that can be called by
scantextfiles.exe. This stand alone function will use the MeasureString
method to get the length of some of the text in the text files. I'm not
putting that function in scantextfiles.exe because I need to call it froma
couple other places as well. So I'm thinking this needs to be a dll that I
can just plop into a folder somewhere. But I have really no idea how to do
that. I've never created a dll before. I'm not sure that's the best way to
go anyway. To make things a little more complicated (maybe) I'm using vb
2005 express to do all of this.

I created a test dll project and my class1.vb code is as follows (just to
try all this out):

Imports System.Math

Public Class Class1

Private Function fncSqRt(ByVal inputval As Double) As Double

If inputval < 0 Then
Return -1
Else
Return Sqrt(inputval)
End If

End Function

End Class

I compiled the dll and so I have TestDLL.dll sitting in my release folder..

Ok, so now what? :) I really am not sure if I'm headed in the right
direction. I'm also not sure how to call the dll from scantextfiles.exe. I
know a lot of this is going to sound pretty basic but like I said, this is a
new area to me. Any help or pionting me in the right direction would be
appreciated.

TIA,

Keith

Keith,
After you compiled your DLL (class), now you're ready to reference it
from your main .exe project by following:

1- Open your main project,
2-In Solution Explorer -> Right click your project
3-Click "Add Reference"
4-Go to "Browse" tab and locate your DLL if your DLL isn't present at
the same project (you could have included it in the same project and
could have called it directly, doesn't matter)

..and now you can instantiate your class from your main project and
use the functions like from a button click event or elsewhere:

'-------Begin--------

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click

Dim instance As New Class1
instance.fncSqRt("parameter_here")

End Sub

'-------End-----


Hope this helps,

Onur Güzel
 
K

Keith G Hicks

OK. It's working. Thank you for all the notes on this (Onur too). But I have
a couple of questions.

First, some samples I found earlier had this sort of thing in the calling
exe's code:

Imports FNTNoticeImport.GetRoot

Module GetRoot

Declare Auto Function GetMyRoot Lib "C:\My
Projects\ImportEmailedNoticesIntoFNT\TestDLL\bin\Release\TestDLL.dll" (ByVal
x As Double) As Double

End Module

Does adding the "reference" to the project mean that's not necessary? I did
it as you suggested below and commented out the above and it all worked. I'm
guessing the idea above might be for older types of code (vb6 manybe?)? That
didn't work anyway because I kept getting entry point errors.

Second, since I had to browse to the reference, and it seems that the path
to the dll is stored in the project, how do I deal with that? Does it just
"look like" a hard coded path? Since the compile process puts a copy of the
dll in the release folder, does it expect the dll to be in it's same
folder? What about calling the dll from another program as I mentioned I
need to do? Can I register the dll on a machine and call it from other
machines without them having to know exactly where it's located?


Keith
 
P

Phill W.

Keith said:
OK. It's working. Thank you for all the notes on this (Onur too). But I have
a couple of questions.

First, some samples I found earlier had this sort of thing in the calling
exe's code:

Imports FNTNoticeImport.GetRoot
Module GetRoot
Declare Auto Function GetMyRoot Lib "C:\My
Projects\ImportEmailedNoticesIntoFNT\TestDLL\bin\Release\TestDLL.dll" (ByVal
x As Double) As Double
End Module
Does adding the "reference" to the project mean that's not necessary?

Yes.

Adding references and creating objects is the ".Net way" of using
..Net-created dll's. The "Declare" method, above, (and it's newer
equivalent, the "DllImport" Attribute) are used to access native Windows
dll's. Unless you need to reach into, say, the Windows API, I'd
recommend you avoid them and stick to references.
I did it as you suggested below and commented out the above and it
all worked. I'm guessing the idea above might be for older types
of code (vb6 maybe?)?

Actually, more like C++ and even Assembler!
That didn't work anyway because I kept getting entry point errors.

It's quite difficult to build a native dll in .Net. Not impossible, but
more often than not just not worth the effort.
Second, since I had to browse to the reference, and it seems that the path
to the dll is stored in the project, how do I deal with that? Does it just
"look like" a hard coded path? Since the compile process puts a copy of the
dll in the release folder, does it expect the dll to be in it's same
folder?

At run-time, it will load this dll from the directory that contains the
program that needs it so deploy both .exe and .dll alongside one another
and things should work.
What about calling the dll from another program as I mentioned I
need to do? Can I register the dll on a machine and call it from other
machines without them having to know exactly where it's located?

Ah; now that's one of the "next steps" - adding your Assembly to the
Global Assembly Cache. For that, you need to make some changes to your
dll project:

(1) "Fix" the Assembly version.
In the AssemblyInfo file (or wherever your version of 'Studio sets it),
set the Assembly Version to a fixed value, say "1.0.0.0". Doesn't
matter /what/ value, just get rid of those asterisks ("1.0.*")! The
asterisks cause the Assembly Version to be "generated" each time you
open the project and, when the GAC is involved, a different assembly
/version/ effectively means a totally different /assembly/.

(2) Strongly Name the assembly.
For this, you need a Strong Naming Key (.snk) File. Create yourself one
and put it in a /very/ safe place. IMHO, you should use the /same/ .snk
file for every Assembly that you want to Strongly Name. (I'm afraid
it's that long since I created mine, I've forgotten how!).
Include this in your project settings and rebuild the assembly.

(3) Use GacUtil to "register" it.
Find gacutil.exe (part of the SDK) and feed your dll into it:

....\gacutil.exe -i <name>.dll

(Even better, set this up as an "External Tool" in studio - saves you
popping up DOS prompts all over the place).

With all that done, remove and re-add the reference in your .exe project
- you should notice that the local copy of the dll /disappears/. All
your programs should now go to the GAC to load your dll.
If you rebuild the dll assembly, remember to re-add it to the GAC - if
you don't, then adding a reference to it will go back to the original,
local copy way of working.

Of course, deploying the dll assembly to (and registering in on) your
client machines might prove a little interesting ... ;-)

HTH,
Phill W.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top