Calling C written DLL from C# 
Author Message
 Calling C written DLL from C#

Hello!

I have a very serious problem by calling a c-written DLL from C#.
The declaration of the DLL looks like this:

DllExport void WINAPI LSVASignature(void *lpJPEG, int iSize, void *lpSig);

lpJPEG - inputstring
iSize - length of inputstring
lpSig - output: manipulated string.

how can I catch the output parameter? Now I'm trying something like that:

        [DllImport("Sig.dll")]
        private static extern unsafe void GetSignature(
            [In]void *buf,
            int l,
            [Out]void *sig_buf
        );

        public static unsafe string CheckDataSignature(string inputString) {
            IntPtr bufPtr;
            IntPtr sig_bufPtr;
            string testStr = "";

            bufPtr = Marshal.StringToHGlobalAnsi(inputString);
            sig_bufPtr = Marshal.StringToHGlobalAnsi(testStr);

            GetSignature(bufPtr.ToPointer(), inputString.Length,
                sig_bufPtr.ToPointer());

            return Marshal.PtrToStringAuto(sig_bufPtr);
        }

Can anybody help me?



Mon, 30 May 2005 17:38:06 GMT  
 Calling C written DLL from C#


Quote:
> Hello!

> I have a very serious problem by calling a c-written DLL from
> C#. The declaration of the DLL looks like this:

> DllExport void WINAPI LSVASignature(void *lpJPEG, int iSize,
> void *lpSig);

> lpJPEG - inputstring
> iSize - length of inputstring
> lpSig - output: manipulated string.

> how can I catch the output parameter?

Markus,

You shouldn't need to use unsafe code to do this.  I usually start
with the simplest possible function signature and only make it
more complex if necessary.  In this case, simply using String and
StringBuilder might work.  The CLR usually takes care of the messy
pointer conversions behind the scenes.

  [DllImport("Sig.dll")]
  private static extern void GetSignature(
    System.String buf,
    int l,
    ref System.Text.StringBuilder sig_buf
  );

  public static string CheckDataSignature(string inputString) {
    StringBuilder outputBuffer = new StringBuilder(255);

    GetSignature(inputString, inputString.Length,
      ref outputBuffer);

    return outputBuffer.ToString();
  }

Hope this helps.

Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/



Mon, 30 May 2005 21:44:45 GMT  
 Calling C written DLL from C#
Markus,

I have not had the opportunity to call C dlls from C#
but I have done it many times with VB.NET.  I'm
posting the code I used

Pat

'
' VB.Net
'
Imports System
Imports System.Text
Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Sequential)> Public Structure Foo
    Public AccessStatus As Integer
    Public UserLoginID As Integer
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)>
Public Capability() As Byte
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)>
Public VoicePath() As Byte
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)>
Public Password() As Byte
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)>
Public UserName() As Byte
    Public Sub New(ByVal intUnsage As Integer)
        ReDim Capability(128)
        ReDim VoicePath(128)
        ReDim UserName(20)
        ReDim Password(20)
    End Sub
End Structure

Public Module TestingPassingUDT

    <DllImport("c:\pat\exe\testpassingudt")> Private
Function _
        TestPassing(ByRef f As Foo) As Integer
    End Function

    Public Sub Main()
        Dim f As Foo = New Foo(0)
        Dim status As Integer
        Dim strData As String
        Dim intPosition As Integer
        f.AccessStatus = 10
        f.UserLoginID = 255
        Encoding.ASCII.GetBytes("Hello world".ToCharArray
(), 0, 11, f.UserName, 0)
        Encoding.ASCII.GetBytes("My Password".ToCharArray
(), 0, 11, f.Password, 0)
        f.UserName(15) = 0
        status = TestPassing(f)
        Console.WriteLine("CS {0:X}", status)
        strData = Encoding.ASCII.GetString(f.UserName)
        intPosition = strData.IndexOf(Chr(0))
        strData = strData.Substring(0, intPosition)
        Console.WriteLine("UN ={0}=", strData)
        Console.WriteLine("UN <{0}>",
Encoding.ASCII.GetString(f.UserName))
        Console.WriteLine("PW <{0}>",
Encoding.ASCII.GetString(f.Password))
        Console.WriteLine("VP <{0}>",
Encoding.ASCII.GetString(f.VoicePath))
        Console.WriteLine("CP <{0}>",
Encoding.ASCII.GetString(f.Capability))
        Console.WriteLine("AS {0:X}", f.AccessStatus)
        Console.WriteLine("UL {0:X}", f.UserLoginID)
    End Sub

End Module

#
# def
#

LIBRARY TestPassingUDT
EXPORTS

//
// C code (actual c++)
//

#include <windows.h>
#include <stdio.h>

typedef struct
    {
        int                  AccessStatus;
        int                  UserLoginID;
        BYTE                 abytCapability [ 128 ];
        BYTE                 abytVoicePath [ 128 ];
        BYTE                 abytPassword [ 20 ];
        BYTE                 abytUserName [ 20 ];
        }   TypeTestPassingUDT;

extern "C"  __declspec(dllexport) DWORD __stdcall
TestPassing

    (TypeTestPassingUDT     * pUserData)

{
char                           szTemp [ 128 ];

memcpy (szTemp,
        (char *) pUserData->abytUserName,
        16);
szTemp [ 16 ] = 0;
printf ("DLL UserName <%s>\n",szTemp);

memcpy (szTemp,
        (char *) pUserData->abytPassword,
        16);
szTemp [ 16 ] = 0;
printf ("DLL Password <%s>\n",szTemp);

sprintf ((char *) pUserData->abytUserName,
         "{HI-%s}",
         szTemp);
strcpy ((char *) pUserData->abytVoicePath,
        "J:VoicePath");
strcpy ((char *) pUserData->abytCapability,
        "This is the capability");
pUserData->AccessStatus = 0x12345678;
pUserData->UserLoginID = 0xFEDCBA98;
return 0xAABBCCDD;

Quote:
}   // TestPassing ()
>-----Original Message-----
>Hello!

>I have a very serious problem by calling a c-written DLL
from C#.
>The declaration of the DLL looks like this:

>DllExport void WINAPI LSVASignature(void *lpJPEG, int

iSize, void *lpSig);
Quote:

>lpJPEG - inputstring
>iSize - length of inputstring
>lpSig - output: manipulated string.

>how can I catch the output parameter? Now I'm trying

something like that:
Quote:

>        [DllImport("Sig.dll")]
>        private static extern unsafe void GetSignature(
>            [In]void *buf,
>            int l,
>            [Out]void *sig_buf
>        );

>        public static unsafe string CheckDataSignature

(string inputString) {
Quote:
>            IntPtr bufPtr;
>            IntPtr sig_bufPtr;
>            string testStr = "";

>            bufPtr = Marshal.StringToHGlobalAnsi
(inputString);
>            sig_bufPtr = Marshal.StringToHGlobalAnsi
(testStr);

>            GetSignature(bufPtr.ToPointer(),
inputString.Length,
>                sig_bufPtr.ToPointer());

>            return Marshal.PtrToStringAuto(sig_bufPtr);
>        }

>Can anybody help me?
>.



Tue, 31 May 2005 01:05:28 GMT  
 Calling C written DLL from C#
Forgive me if I'm wrong, but just sending a System.String to the runtime to
be marshalled, it will marshal it as a double-byte array correct? So you'll
only get the first character when viewing it as a character array from a C
DLL. This probably isn't what you want. If I'm wrong, then tell me. Here's
the code for a simple C DLL and C# console application that calls it. I've
compiled this using the VS7 so I know it works.

Ben

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
 class Class1
 {
  [STAThread]
  static void Main(string[] args)
  {
   string inputString = "Hello World";
   byte[] b = new byte[256];
   callme(inputString,inputString.Length,b);
   String s =
    System.Text.Encoding.Default.GetString
    (b);
   Console.WriteLine(s);
  }
  [DllImport("dddd.dll",CharSet=CharSet.Auto)]
  static extern void callme(
   [MarshalAs(UnmanagedType.LPStr)]
   string inputstring, System.Int32 length, byte[] b);
 }

Quote:
}

// dddd.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;

#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
    return TRUE;

Quote:
}

EXPORT void CALLBACK callme(char* inputString,int length, char b[])
{
 strncpy(b,inputString,length);
 strcat(b," Again!");
 return;

Quote:
}



Quote:


> > Hello!

> > I have a very serious problem by calling a c-written DLL from
> > C#. The declaration of the DLL looks like this:

> > DllExport void WINAPI LSVASignature(void *lpJPEG, int iSize,
> > void *lpSig);

> > lpJPEG - inputstring
> > iSize - length of inputstring
> > lpSig - output: manipulated string.

> > how can I catch the output parameter?

> Markus,

> You shouldn't need to use unsafe code to do this.  I usually start
> with the simplest possible function signature and only make it
> more complex if necessary.  In this case, simply using String and
> StringBuilder might work.  The CLR usually takes care of the messy
> pointer conversions behind the scenes.

>   [DllImport("Sig.dll")]
>   private static extern void GetSignature(
>     System.String buf,
>     int l,
>     ref System.Text.StringBuilder sig_buf
>   );

>   public static string CheckDataSignature(string inputString) {
>     StringBuilder outputBuffer = new StringBuilder(255);

>     GetSignature(inputString, inputString.Length,
>       ref outputBuffer);

>     return outputBuffer.ToString();
>   }

> Hope this helps.

> Chris.
> -------------
> C.R. Timmons Consulting, Inc.
> http://www.crtimmonsinc.com/



Tue, 31 May 2005 01:10:22 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Newbie: separate big .cs file into small .cs files

2. Calling classes in other cs files

3. How to show/call Form2.cs from Form1.cs ?

4. include another form(cs) in C#?

5. Include code in other Cs files

6. Reuse of cs files, namespace, arch advice pls

7. word - automatic numbering/bold/underline/italics

8. How to Generate .cs file at Runtime

9. newbe/cs student, need help w/ code

10. Serial.cs

11. Compile CS source code using ICodeCompiler

12. Two CS files (using namespaces)

 

 
Powered by phpBB® Forum Software