How do I Import Dll and call sub?

  • Thread starter Thread starter Nicolas
  • Start date Start date
Yes I agree with the common interface and it's a great idea that I try but
still having an error with constructor for some reason that I don't
understand.
 
I know.
In my case I did 3 assemblies
Solution
Project ddlA
Project dllB
Project mainDll

Copy the compile dllA and dllB into the release folder of mainDll (to
pretend that the customer would only add the supplied dlls to his main
application)

Compile and run mainDll and Kaboom, construction error...

May be I'm doing something wrong or forgeting something stupid in the way.
 
Try this: (add the marked lines only)

For Each t In ass.GetTypes
Console.WriteLine(t.Namespace & " : " & t.Name)

If t.Name.ToLower = "cA".ToLower Then
'--------
Dim ctors = t.GetConstructors()
For Each ctor In ctors
Console.WriteLine("Constructor: " & ctor.Name)
For Each param In ctor.GetParameters
Console.Write(" " & param.Name & ": ")
Console.WriteLine(param.ParameterType.FullName)
Next
Next
'--------

'o = Activator.CreateInstance(t, obj)
Console.WriteLine(o Is Nothing)
Exit For
End If
Next


Which output do you get from the additional lines?
 
And the error message is ? I gave this a try, it works and the code looks
like (I defined a Name function in my interface rather than a DoThis method)
:

Const FileName As String = "ClassLibrary2.dll"
Dim assembly As Assembly = assembly.LoadFrom(Application.StartupPath
& "\" & FileName)
Dim o As ITest = Nothing
For Each t As Type In Assembly.GetTypes
If Not t.GetInterface("ITest") Is Nothing Then
o = CType(Activator.CreateInstance(t, "MyArg"), ITest)
End If
Next
If Not o Is Nothing Then
MsgBox(o.Name)
End If

If the constructor is not found :
- double check you are loading a correct DLL (and not an old one that
wouldn't have the constructor)
- could it be a parameter type mismatch (ie the constructor expects a string
and you pass an integer) ?
 
I guess it is returning the proper thing myParam as String
************ CODE ****************
obj = New Object() {"Nicolas"}
'
ass = Assembly.LoadFrom(thisDLL)
Console.WriteLine(ass.GetName.Name)

Console.WriteLine("Types:")
For Each t In ass.GetTypes
Console.WriteLine(t.Namespace & " : " & t.Name) ' & " = " &
t.IsInterface)
If t.Name.ToLower = "cA".ToLower Then

Dim ctor As ConstructorInfo
Dim param As ParameterInfo

For Each ctor In t.GetConstructors()
Console.WriteLine("Constructor:" & ctor.Name)

For Each param In ctor.GetParameters
Console.Write(vbTab & param.Name & ":")
Console.WriteLine(param.ParameterType.FullName)
Next

Next

o = Activator.CreateInstance(t, obj)
Console.WriteLine(o Is Nothing)
Exit For
End If
Next


*********** CONSOLE **************************

Starting...
dllA
Types:
dllA.My : MyApplication
dllA.My : MyComputer
dllA.My : MyProject
dllA.My : MyWebServices
dllA.My : ThreadSafeObjectProvider`1
dllA.NA : iA
dllA.NA : cA
Constructor:.ctor
myParam:System.String

Constructor on type 'dllA.NA.cA' not found.
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder
bin
der, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr,
Binde
r binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, Object[] args)
at maindll.Module1.launchDll(String thisDLL) in
D:\Work\test\maindll\maindll\
Module1.vb:line 80
 
Nicolas said:
I guess it is returning the proper thing myParam as String
************ CODE ****************
obj = New Object() {"Nicolas"}


Hit me if you can! ;) As you didn't enable Option Strict - I recommend
to do it - I had to change the declaration of 'obj' from Object to
Object(). Otherwise I couldn't compile your code.

Dim obj As Object()
 
Got it.
My parameter was like:
dim o as Object
o= New Object(){"Nicolas"}
Where now it work like
o="Nicolas"

Always something stupid, Thank you very very much for all your help and
support
 
Got it.
My parameter was like:
dim o as Object
o= New Object(){"Nicolas"}
Where now it work like
o="Nicolas"

Always something stupid, Thank you very very much for all your help and
support
 
Armin said:
Hit me if you can! ;) As you didn't enable Option Strict - I recommend
to do it - I had to change the declaration of 'obj' from Object to
Object(). Otherwise I couldn't compile your code.

Dim obj As Object()

Forgot the explanation:

The 2nd parameter of
activator.createinstance(t, obj)
is a ParamArray.


When calling createinstance, if the declaration is

dim obj as Object

the compiler creates the code to create a new array at runtime and copy
the content of variable obj to index 0. Therefore, the first parameter
passed to the constructor is of type Object(), not of type String as
required.


Whereas, if the declaration is

dim obj as Object()

the compiler passes the array referenced by variable obj. The item and
index 0 is a String. Therefore it succeeds.
 
I created in VB.Net two dlls projects. dllA and dllB both will have the same
subs/functions name but do different things.
They have classes with interfaces as seen below.

How from a third dll project (dllC) can I call those subs
Seems that I always missed an entrypoint. or something.
Those dlls are all store in the same folder as the dllC.

Thank you very much for the help.

Code EXAMPLE:
dllA
Namespace NA
Interface iA
sub doThis(byVal a string)
End Interface

Class cA
implements iA

sub New(myParam as string)
'..... do something
end sub

private sub doThis(byVal a as string) implements iA.doThis
'do something with a
end sub

end Class
end Namespace
--------------------------------------
dllB
Namespace NB
Interface iB
sub doThis(byVal b string)
End Interface

Class cB
implements iB

sub New(myParam as string)
'..... do something
end sub

private sub doThis(byVal b as string) implements iB.doThis
'do something with b
end sub

end Class
end Namespace
--------------------------------------
dllC
Namespace C
Class C
dim thisDLL as string

'Set thisDll with the name that correspond to the needs
'Assuming that I want dllB
thisDll = "dllB"
'WHAT to Do from here to be able to call that dll and that sub?

myDll.doThis(myvalue)

end Class
end Namespace

If you using .net 3.5 - have you looked at the System.AddIn namespace. From a
quick glance of this thread - it sure looks like that your trying to implement
a plugin type system... And if you are, why reinvent the wheel - it's built
in already.
 
I have to deliver this project for Framework 2.0. However I will look into
your suggestion (System.Addin) in more detail and see if it can be
implemented in future release.

Thanks
 
Back
Top