Shared functions not accessible

  • Thread starter Thread starter tshad
  • Start date Start date
T

tshad

I have a Dll I created in VS 2000.

The namespace is MyFunctions and the Class is CryptoUtil.

I have a program that is using the Class but it can't access it directly.

I have a class (below) called CryptoUtil.

The functions are Shared functions. I have this Dll in the bin folder of my
program. If I don't reference it - it can't seem to find it. If I have:

Import MyFunctions

I still can't access my function Encode directly (error: Name Encode not
declared)

I can't access it as: CryptoUtil.Encode (Encode is not a member of
CryptoUtil ????)

I can't access it as: MyFunctions.CryptoUtil.Encode (CryptoUtil is not a
member of MyFunctions?? - it isn't?)

This does work: CryptoUtil.MyFunctions.CryptoUtil.Encode. This makes
absolutely not sense to me at all unless it is because I am using a shared
routine.

I have another Dll (newHire) in the same folder that starts out:

****************************************
namespace MyFunctions
{
[Serializable]
public class NewHire
*****************************************

I can access this class as: newHire = New NewHire

What is the difference? Here is the CryptoUtil class:

***************************************************


Imports System

Namespace MyFunctions

Public Class CryptoUtil

Enum EncryptionAlgorithm
Des = 1
Rc2 = 2
Rijndael = 3
TripleDes = 4
End Enum

Public Shared Function Encode(ByVal value As String, ByVal key As
String) As String
Return TripleDESEncode(value, key)
End Function

Public Shared Function Decode(ByVal value As String, ByVal key As
String) As String
Return TripleDESDecode(value, key)
End Function

Public Shared Function TripleDESEncode(ByVal value As String, ByVal
key As String) As String
Dim des As New
Security.Cryptography.TripleDESCryptoServiceProvider
des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key,
New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("TripleDES", "MD5", 168, New
Byte(7) {})
Dim ms As New IO.MemoryStream((value.Length * 2) - 1)
Dim encStream As New Security.Cryptography.CryptoStream(ms,
des.CreateEncryptor(), Security.Cryptography.CryptoStreamMode.Write)
Dim plainBytes As Byte() = Text.Encoding.UTF8.GetBytes(value)
encStream.Write(plainBytes, 0, plainBytes.Length)
encStream.FlushFinalBlock()
Dim encryptedBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(encryptedBytes, 0, CInt(ms.Length))
encStream.Close()
Return Convert.ToBase64String(encryptedBytes)
End Function

Public Shared Function TripleDESDecode(ByVal value As String, ByVal
key As String) As String
Dim des As New
Security.Cryptography.TripleDESCryptoServiceProvider
des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key,
New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("TripleDES", "MD5", 168, New
Byte(7) {})
Dim encryptedBytes As Byte() = Convert.FromBase64String(value)
Dim ms As New IO.MemoryStream(value.Length)
Dim decStream As New Security.Cryptography.CryptoStream(ms,
des.CreateDecryptor(), Security.Cryptography.CryptoStreamMode.Write)
decStream.Write(encryptedBytes, 0, encryptedBytes.Length)
decStream.FlushFinalBlock()
Dim plainBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(plainBytes, 0, CInt(ms.Length))
decStream.Close()
Return Text.Encoding.UTF8.GetString(plainBytes)
End Function

End Class
End Namespace
****************************************************

Thanks,

Tom
 
Also,

I would have assumed that you would call the function by Class.Function and
Import the Namespace (which was not working).

In this document - http://www.aspnet101.com/aspnet101/tutorials.aspx?id=43 -
it shows it as being able to be called by Class.Function.

*******************************************************
Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.UI
Imports System.Web.UI.WebControls

NameSpace ASPNet101

Public Class LB
Public Shared strConn as string =
"server=YourServer;uid=YourUID;pwd=YourPWD;database=Your_DB"
Public Shared MyConn as New SQLConnection(strConn)
Public Shared MySQL as String
Public Shared objDR as SqlDataReader

Public Shared Function FillListBox(LBName as ListBox, TblName as String,
TblField as String, TblID as String)
MySQL = "Select " & TblField & ", " & TblID & " from " & TblName
MyConn.Open()
Dim Cmd as New SQLCommand(MySQL, MyConn)
objDR=Cmd.ExecuteReader(system.data.CommandBehavior.CloseConnection)
lbName.DataSource = objDR
lbName.DataTextField=TblField
lbName.DataValueField=TblID
lbName.DataBind()
MyConn.Close()
End Function

End Class

End Namespace
*******************************************************

This can be called by LB.FillListBox(...).

What is different from my class?

Thanks,

Tom

tshad said:
I have a Dll I created in VS 2000.

The namespace is MyFunctions and the Class is CryptoUtil.

I have a program that is using the Class but it can't access it directly.

I have a class (below) called CryptoUtil.

The functions are Shared functions. I have this Dll in the bin folder of
my program. If I don't reference it - it can't seem to find it. If I
have:

Import MyFunctions

I still can't access my function Encode directly (error: Name Encode not
declared)

I can't access it as: CryptoUtil.Encode (Encode is not a member of
CryptoUtil ????)

I can't access it as: MyFunctions.CryptoUtil.Encode (CryptoUtil is not a
member of MyFunctions?? - it isn't?)

This does work: CryptoUtil.MyFunctions.CryptoUtil.Encode. This makes
absolutely not sense to me at all unless it is because I am using a shared
routine.

I have another Dll (newHire) in the same folder that starts out:

****************************************
namespace MyFunctions
{
[Serializable]
public class NewHire
*****************************************

I can access this class as: newHire = New NewHire

What is the difference? Here is the CryptoUtil class:

***************************************************


Imports System

Namespace MyFunctions

Public Class CryptoUtil

Enum EncryptionAlgorithm
Des = 1
Rc2 = 2
Rijndael = 3
TripleDes = 4
End Enum

Public Shared Function Encode(ByVal value As String, ByVal key As
String) As String
Return TripleDESEncode(value, key)
End Function

Public Shared Function Decode(ByVal value As String, ByVal key As
String) As String
Return TripleDESDecode(value, key)
End Function

Public Shared Function TripleDESEncode(ByVal value As String, ByVal
key As String) As String
Dim des As New
Security.Cryptography.TripleDESCryptoServiceProvider
des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key,
New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("TripleDES", "MD5", 168, New
Byte(7) {})
Dim ms As New IO.MemoryStream((value.Length * 2) - 1)
Dim encStream As New Security.Cryptography.CryptoStream(ms,
des.CreateEncryptor(), Security.Cryptography.CryptoStreamMode.Write)
Dim plainBytes As Byte() = Text.Encoding.UTF8.GetBytes(value)
encStream.Write(plainBytes, 0, plainBytes.Length)
encStream.FlushFinalBlock()
Dim encryptedBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(encryptedBytes, 0, CInt(ms.Length))
encStream.Close()
Return Convert.ToBase64String(encryptedBytes)
End Function

Public Shared Function TripleDESDecode(ByVal value As String, ByVal
key As String) As String
Dim des As New
Security.Cryptography.TripleDESCryptoServiceProvider
des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key,
New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("TripleDES", "MD5", 168, New
Byte(7) {})
Dim encryptedBytes As Byte() = Convert.FromBase64String(value)
Dim ms As New IO.MemoryStream(value.Length)
Dim decStream As New Security.Cryptography.CryptoStream(ms,
des.CreateDecryptor(), Security.Cryptography.CryptoStreamMode.Write)
decStream.Write(encryptedBytes, 0, encryptedBytes.Length)
decStream.FlushFinalBlock()
Dim plainBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(plainBytes, 0, CInt(ms.Length))
decStream.Close()
Return Text.Encoding.UTF8.GetString(plainBytes)
End Function

End Class
End Namespace
****************************************************

Thanks,

Tom
 
The problem seems to be with VS 2000. I built the Dll using VS 2000 as a
Class Library.

If I just take the .vb file and use a commandline build it works fine.

vbc /t:library crypto.vb

I can now do:
************************
Import MyFunctions
....
CryptoUtil.Encode
*************************

I do need to Add the reference to CryptoUtil even though I put the dll in
both the Bin and Debug folder. I would have thought that the project would
look there for its dlls.

Tom

tshad said:
Also,

I would have assumed that you would call the function by Class.Function
and Import the Namespace (which was not working).

In this document -
http://www.aspnet101.com/aspnet101/tutorials.aspx?id=43 - it shows it as
being able to be called by Class.Function.

*******************************************************
Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.UI
Imports System.Web.UI.WebControls

NameSpace ASPNet101

Public Class LB
Public Shared strConn as string =
"server=YourServer;uid=YourUID;pwd=YourPWD;database=Your_DB"
Public Shared MyConn as New SQLConnection(strConn)
Public Shared MySQL as String
Public Shared objDR as SqlDataReader

Public Shared Function FillListBox(LBName as ListBox, TblName as String,
TblField as String, TblID as String)
MySQL = "Select " & TblField & ", " & TblID & " from " & TblName
MyConn.Open()
Dim Cmd as New SQLCommand(MySQL, MyConn)
objDR=Cmd.ExecuteReader(system.data.CommandBehavior.CloseConnection)
lbName.DataSource = objDR
lbName.DataTextField=TblField
lbName.DataValueField=TblID
lbName.DataBind()
MyConn.Close()
End Function

End Class

End Namespace
*******************************************************

This can be called by LB.FillListBox(...).

What is different from my class?

Thanks,

Tom

tshad said:
I have a Dll I created in VS 2000.

The namespace is MyFunctions and the Class is CryptoUtil.

I have a program that is using the Class but it can't access it directly.

I have a class (below) called CryptoUtil.

The functions are Shared functions. I have this Dll in the bin folder of
my program. If I don't reference it - it can't seem to find it. If I
have:

Import MyFunctions

I still can't access my function Encode directly (error: Name Encode not
declared)

I can't access it as: CryptoUtil.Encode (Encode is not a member of
CryptoUtil ????)

I can't access it as: MyFunctions.CryptoUtil.Encode (CryptoUtil is not a
member of MyFunctions?? - it isn't?)

This does work: CryptoUtil.MyFunctions.CryptoUtil.Encode. This makes
absolutely not sense to me at all unless it is because I am using a
shared routine.

I have another Dll (newHire) in the same folder that starts out:

****************************************
namespace MyFunctions
{
[Serializable]
public class NewHire
*****************************************

I can access this class as: newHire = New NewHire

What is the difference? Here is the CryptoUtil class:

***************************************************


Imports System

Namespace MyFunctions

Public Class CryptoUtil

Enum EncryptionAlgorithm
Des = 1
Rc2 = 2
Rijndael = 3
TripleDes = 4
End Enum

Public Shared Function Encode(ByVal value As String, ByVal key As
String) As String
Return TripleDESEncode(value, key)
End Function

Public Shared Function Decode(ByVal value As String, ByVal key As
String) As String
Return TripleDESDecode(value, key)
End Function

Public Shared Function TripleDESEncode(ByVal value As String,
ByVal key As String) As String
Dim des As New
Security.Cryptography.TripleDESCryptoServiceProvider
des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key,
New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("TripleDES", "MD5", 168, New
Byte(7) {})
Dim ms As New IO.MemoryStream((value.Length * 2) - 1)
Dim encStream As New Security.Cryptography.CryptoStream(ms,
des.CreateEncryptor(), Security.Cryptography.CryptoStreamMode.Write)
Dim plainBytes As Byte() = Text.Encoding.UTF8.GetBytes(value)
encStream.Write(plainBytes, 0, plainBytes.Length)
encStream.FlushFinalBlock()
Dim encryptedBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(encryptedBytes, 0, CInt(ms.Length))
encStream.Close()
Return Convert.ToBase64String(encryptedBytes)
End Function

Public Shared Function TripleDESDecode(ByVal value As String,
ByVal key As String) As String
Dim des As New
Security.Cryptography.TripleDESCryptoServiceProvider
des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key,
New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("TripleDES", "MD5", 168, New
Byte(7) {})
Dim encryptedBytes As Byte() = Convert.FromBase64String(value)
Dim ms As New IO.MemoryStream(value.Length)
Dim decStream As New Security.Cryptography.CryptoStream(ms,
des.CreateDecryptor(), Security.Cryptography.CryptoStreamMode.Write)
decStream.Write(encryptedBytes, 0, encryptedBytes.Length)
decStream.FlushFinalBlock()
Dim plainBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(plainBytes, 0, CInt(ms.Length))
decStream.Close()
Return Text.Encoding.UTF8.GetString(plainBytes)
End Function

End Class
End Namespace
****************************************************

Thanks,

Tom
 
tshad said:
I have a Dll I created in VS 2000.

The namespace is MyFunctions and the Class is CryptoUtil.

I have a program that is using the Class but it can't access it directly.

I have a class (below) called CryptoUtil.

The functions are Shared functions. I have this Dll in the bin folder of my
program. If I don't reference it - it can't seem to find it.

If you are using functions is an assembly outside your main program,
then you [normally] *have* to have a reference to it in your project.

"Imports" statements /do not/ get additional functionality - that's what
References are for.
All the Imports statements do is allow you to shorten what you have to
type in code, as in

With "Imports System.Data":

Dim ds as New DataSet
ds.Tables.Add(New DataTable)

Without "Imports System.Data":

Dim ds as New System.Data.DataSet
ds.Tables.Add(New System.Data.DataTable)

This does work: CryptoUtil.MyFunctions.CryptoUtil.Encode. This makes
absolutely not sense to me at all unless it is because I am using a shared
routine.

Check out the Properties of your DLL project, specifically the Root
Namespace property - this gets set to the Project name by default and
seems to be used as a prefix for namespaces within the project - IMHO,
more trouble that it's worth.
I /always/ blank this property out.

HTH,
Phill W.
 
tshad said:
The problem seems to be with VS 2000. I built the Dll using VS 2000 as a
Class Library.

If I just take the .vb file and use a commandline build it works fine.

vbc /t:library crypto.vb

I can now do:
************************
Import MyFunctions
...
CryptoUtil.Encode
*************************

I do need to Add the reference to CryptoUtil even though I put the dll in
both the Bin and Debug folder. I would have thought that the project would
look there for its dlls.

Look in the properties of your project. What is the root namespace?
You must prefix calls to your shared methods using the root namespace.
When you use the Namespace keyword, that is automatically prefixed by
the root namespace.

To fix it, either 1) remove the root namespace and just use the
Namespace keyword. OR 2) remove the Namespace keyword and set the root
namespace appropriately. OR 3) use a combination of both, setting the
root namespace and then using the Namespace keyword to refine it.

For example, assume that the root namespace is set to "Root" and you
have this code:

Namespace MyNamespace
Public Class SomeClass
Shared Sub SomeSub()
'Code
End Sub
End Class
End Namespace

To access the shared sub, you must use:
Root.MyNamespace.SomeClass.SomeSub().

You can use the Import statement to shorten that as necessary.

Hope this helps you clear up your mystery.

Chris
 
Chris Dunaway said:
Look in the properties of your project. What is the root namespace?
You must prefix calls to your shared methods using the root namespace.
When you use the Namespace keyword, that is automatically prefixed by
the root namespace.

To fix it, either 1) remove the root namespace and just use the
Namespace keyword. OR 2) remove the Namespace keyword and set the root
namespace appropriately. OR 3) use a combination of both, setting the
root namespace and then using the Namespace keyword to refine it.

For example, assume that the root namespace is set to "Root" and you
have this code:

Namespace MyNamespace
Public Class SomeClass
Shared Sub SomeSub()
'Code
End Sub
End Class
End Namespace

To access the shared sub, you must use:
Root.MyNamespace.SomeClass.SomeSub().

You can use the Import statement to shorten that as necessary.

Hope this helps you clear up your mystery.

It does.

Thanks,

Tom
 
Phill W. said:
tshad said:
I have a Dll I created in VS 2000.

The namespace is MyFunctions and the Class is CryptoUtil.

I have a program that is using the Class but it can't access it directly.

I have a class (below) called CryptoUtil.

The functions are Shared functions. I have this Dll in the bin folder of
my program. If I don't reference it - it can't seem to find it.

If you are using functions is an assembly outside your main program, then
you [normally] *have* to have a reference to it in your project.

"Imports" statements /do not/ get additional functionality - that's what
References are for.
All the Imports statements do is allow you to shorten what you have to
type in code, as in

With "Imports System.Data":

Dim ds as New DataSet
ds.Tables.Add(New DataTable)

Without "Imports System.Data":

Dim ds as New System.Data.DataSet
ds.Tables.Add(New System.Data.DataTable)
If I set up a reference to a dll that is in a different project and I now
move this dll to another machine, I assume that I will also need to move the
other dll it refers to. Will it find it if both dlls are in the same
folders on the new machine?

For example:

I have a dll called x.dll has a reference to y.dll in the "y" bin folder.

I now move both dlls to another machine in a folder "test".

Will x.dll see y.dll?

Thanks,

Tom
 
VB doesn't support code reuse sorry

VB is completely dead language; go learn a real language.

-Aaron


I have a Dll I created in VS 2000.

The namespace is MyFunctions and the Class is CryptoUtil.

I have a program that is using the Class but it can't access it directly.

I have a class (below) called CryptoUtil.

The functions are Shared functions. I have this Dll in the bin folder of my
program. If I don't reference it - it can't seem to find it. If I have:

Import MyFunctions

I still can't access my function Encode directly (error: Name Encode not
declared)

I can't access it as: CryptoUtil.Encode (Encode is not a member of
CryptoUtil ????)

I can't access it as: MyFunctions.CryptoUtil.Encode (CryptoUtil is not a
member of MyFunctions?? - it isn't?)

This does work: CryptoUtil.MyFunctions.CryptoUtil.Encode. This makes
absolutely not sense to me at all unless it is because I am using a shared
routine.

I have another Dll (newHire) in the same folder that starts out:

****************************************
namespace MyFunctions
{
[Serializable]
public class NewHire
*****************************************

I can access this class as: newHire = New NewHire

What is the difference? Here is the CryptoUtil class:

***************************************************


Imports System

Namespace MyFunctions

Public Class CryptoUtil

Enum EncryptionAlgorithm
Des = 1
Rc2 = 2
Rijndael = 3
TripleDes = 4
End Enum

Public Shared Function Encode(ByVal value As String, ByVal key As
String) As String
Return TripleDESEncode(value, key)
End Function

Public Shared Function Decode(ByVal value As String, ByVal key As
String) As String
Return TripleDESDecode(value, key)
End Function

Public Shared Function TripleDESEncode(ByVal value As String, ByVal
key As String) As String
Dim des As New
Security.Cryptography.TripleDESCryptoServiceProvider
des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key,
New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("TripleDES", "MD5", 168, New
Byte(7) {})
Dim ms As New IO.MemoryStream((value.Length * 2) - 1)
Dim encStream As New Security.Cryptography.CryptoStream(ms,
des.CreateEncryptor(), Security.Cryptography.CryptoStreamMode.Write)
Dim plainBytes As Byte() = Text.Encoding.UTF8.GetBytes(value)
encStream.Write(plainBytes, 0, plainBytes.Length)
encStream.FlushFinalBlock()
Dim encryptedBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(encryptedBytes, 0, CInt(ms.Length))
encStream.Close()
Return Convert.ToBase64String(encryptedBytes)
End Function

Public Shared Function TripleDESDecode(ByVal value As String, ByVal
key As String) As String
Dim des As New
Security.Cryptography.TripleDESCryptoServiceProvider
des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key,
New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("TripleDES", "MD5", 168, New
Byte(7) {})
Dim encryptedBytes As Byte() = Convert.FromBase64String(value)
Dim ms As New IO.MemoryStream(value.Length)
Dim decStream As New Security.Cryptography.CryptoStream(ms,
des.CreateDecryptor(), Security.Cryptography.CryptoStreamMode.Write)
decStream.Write(encryptedBytes, 0, encryptedBytes.Length)
decStream.FlushFinalBlock()
Dim plainBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(plainBytes, 0, CInt(ms.Length))
decStream.Close()
Return Text.Encoding.UTF8.GetString(plainBytes)
End Function

End Class
End Namespace
****************************************************

Thanks,

Tom
 
If I set up a reference to a dll that is in a different project and I now
move this dll to another machine, I assume that I will also need to move the
other dll it refers to.

Correct.
Just like you need all the Framework assemblies that reference as well.
Will it find it if both dlls are in the same folders on the new machine?

Yes, it will.

However, finding the [first] dll from the exe that calls it may be more
"interesting" unless all /three/ are in the same directory... ;-)

HTH,
Phill W.
 
Phill W. said:
If I set up a reference to a dll that is in a different project and I now
move this dll to another machine, I assume that I will also need to move
the other dll it refers to.

Correct.
Just like you need all the Framework assemblies that reference as well.
Will it find it if both dlls are in the same folders on the new machine?

Yes, it will.

However, finding the [first] dll from the exe that calls it may be more
"interesting" unless all /three/ are in the same directory... ;-)
Not sure what you mean here?

Tom
 
tshad said:
Will it find it if both dlls are in the same folders on the new machine?
Yes, it will.

However, finding the [first] dll from the exe that calls it may be more
"interesting" unless all /three/ are in the same directory... ;-)
Not sure what you mean here?

If your program and Dll's all live in the same directory ...

C:\Apps\Bin\ProgA.exe
C:\Apps\Bin\Lib1.dll
C:\Apps\Bin\Lib2.dll

.... then everything's fine. The program can find Lib1, which in turn
can find Lib2. However, if you separate the libraries into another
directory ...

C:\Apps\Bin\ProgA.exe
C:\Apps\Lib\Lib1.dll
C:\Apps\Lib\Lib2.dll

.... then you have to tell the program where to find the dll's. In this
case, I'd use the dependentAssembly and codeBase tags in the program's
App.Config. Once the program finds and loads Lib1, it will look for
Lib2 in the same directory.

Worse still is if you start spreading the dll's around ...

C:\Apps\Bin\ProgA.exe
C:\Apps\Lib1\Lib1.dll
C:\Apps\Lib2\Lib2.dll

.... in which case you need to tell the program where to find /both/
dll's. Here I'd bite the bullet, Strongly Name both Dll's and load them
into the Global Assembly Cache; but that's just me.

Regards,
Phill W.
 
Back
Top