Calling a C-style DLL from C# with only a VB example of how it should work

Posted on 2004-11-25
Medium Priority
Last Modified: 2007-12-19
Hi, I'm just getting started with Interop, and I would appreciate any help you might give me on this question (and others upcoming, I'm sure).

I have been assigned a project which requires me to interact with a regular non-COM DLL.  I don't have any definitions for the library functions, but I have detailed VB examples of how to work with the DLL.  All the documentation regarding converting/marshaling types i've seen requires knowing the original types in the DLL.  I do not have this information.  I have tons of VB examples from the company's SDK, but none that show how to use any .NET language.

The SDK shows this in the C++ bvtypes.h file:
typedef struct {
      char Directory[256];
      char UserID[12];
      char Password[8];
      char LogonDate[8];
} BVLogonRecord;

The Visual Basic examples show the following:
    Type BVLogonRecord
        Directory               As String * 256
        UserID                  As String * 12
        Password                As String * 8
        LogonDate               As String * 8
    End Type

    Declare Function BVLogonWithDir Lib "bvapi.dll" (LogonRecord As BVLogonRecord) As Integer

VB function:
    Dim LogonRecord As BVLogonRecord

    LogonRecord.Directory = "C:\DBDIR"
    LogonRecord.UserID = "USER"
    LogonRecord.Password = "PASSWORD"
    LogonRecord.LogonDate = "20041117"

    result = BVLogonWithDir(LogonRecord)

So, I tried this in C#:
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
 public struct BVLogonRecord
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
   public String Directory;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=12)]
   public String UserID;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=8)]
   public String Password;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=8)]
   public String LogonDate;

[DllImport(@"C:\BV\bvapi.dll", CharSet=CharSet.Ansi)]
public static extern int BVLogonWithDir ([MarshalAs(UnmanagedType.Struct)] ref BVLogonRecord LogonRecord);

public void Logon()
  string dir = @"C:\DBDIR".PadRight(256,' ');
  string usr = "USER".PadRight(12,' ');
  string pwd = "PASSWORD".PadRight(8,' ');
  string dt = "20041117".PadRight(8,' ');

  BVLogonRecord lr = new BVLogonRecord(dir,usr,pwd,dt);

  int result = BVTest.BVLogonWithDir(ref lr);

I have been able to come up with two results:
1)  if I append all the strings together and store them in Directory, then the function works. (regardless of what's stored in the other variables)
2)  everything else I do gives me bad parameter errors, missing paramters,

Thanks very much for any assistance,
Trevor Braun

Question by:TrevStar22
  • 3
  • 2

Expert Comment

ID: 12679321
Try like this,

public void Logon()
  BVLogonRecord lr;
  lr.Directory = @"C:\DBDIR";
  lr.UserID = "USER";
  lr.Password = "PASSWORD";
  lr.LogonDate= "20041117";
  int result = BVTest.BVLogonWithDir(ref lr);
LVL 48

Expert Comment

ID: 12679352
 string dir = @"C:\DBDIR".PadRight(256,' ');
  string usr = "USER".PadRight(12,' ');
  string pwd = "PASSWORD".PadRight(8,' ');
  string dt = "20041117".PadRight(8,' ');

I think these strings are longer than required by function. With NULL chatacter in the end dir has 257 length.
You can remove PadRight, it is not necessary.

 string dir = @"C:\DBDIR";

Expert Comment

ID: 12684841
Hi TrevStar22,

Please make your commect here. Don't post them as feedback. I think you are new to EE. Read help for more ins...


Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Author Comment

ID: 12686394
Thanks Chester.  Yes, I am new to EE.  I'm reading the help now!!  


Author Comment

ID: 12686457
To respond to Chester and Alex properly (i.e. via comments):

Adding 'ref' to the structure got rid of the "object...reference" error.  
I think I am no trying to understand how to change the VB syntax "String    *   256"  to something in C#/.Net.

You are correct about the PadRight.  It isn't needed, however I like being 100% of what's being sent to the DLL.  I checked the length of the structure, it is 284 (as expected), however I don't know if that's due to the SizeConst instructions on each property or not.

Thanks very much for the suggestings.


Accepted Solution

Chester_M_Ragel earned 2000 total points
ID: 12689262

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question