[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Load Win32 dll

Posted on 2005-04-19
11
Medium Priority
?
931 Views
Last Modified: 2012-06-27
hi,
i have a win32 dll that i want to import into my program, and it has one function i need.. the code to import is below

[DllImport("MSUtils.dll")]
private static extern IntPtr GetHashHex(IntPtr source, System.UInt16 key);

also tried

[DllImport("MSUtils.dll")]
private static extern IntPtr GetHashHex(char[] source, System.UInt16 key);

the MSUtils.dll is written in Delphi, and the declaration of that function is:

function GetHashHex(SourceStr: Array of Char; Key: word): PChar; stdcall;

when i call the function declared in the first example, the function sometimes (randomly) succeeds, but it returns a bad pointer IntPtr, which is some value, i cant use...
and when i call the function declared in the second example, the function succeeds, only when i pass small arrays (~300), if char array is larger than 300 (or some near it value), the program throws nullpointer exception...

how should i declare and use that function? and how should i use it?
do i need to allocate some memory or other stuff?

help please...
thanks in advance
0
Comment
Question by:GiedriusS
  • 6
  • 5
11 Comments
 
LVL 8

Expert Comment

by:rajaloysious
ID: 13823008
Should you be using System.Runtime.InteropServices.MarshalAsAttribute
see here...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemRuntimeInteropServicesMarshalasAttributeClassTopic.asp

//Applied to a parameter.
  public void M1 ([MarshalAs(UnmanagedType.LPWStr)]String msg);
//Applied to a field within a class.
  class MsgText {
    [MarshalAs(UnmanagedType.LPWStr)] Public String msg;
  }
//Applied to a return value.
[return: MarshalAs(UnmanagedType.LPWStr)]
public String GetMessage();


cheers
0
 
LVL 8

Expert Comment

by:rajaloysious
ID: 13823024
Also have a look at Marshaling Text  section in
http://msdn.microsoft.com/msdnmag/issues/03/07/NET/

cheers
0
 

Author Comment

by:GiedriusS
ID: 13823671
i still can't find the appropriate types.. i try this definition:

unsafe private static extern IntPtr GetHashHex([MarshalAs(UnmanagedType.LPTStr)] String source, [MarshalAs(UnmanagedType.U2)] System.UInt16 key);

this works with long strings, but it gives the wrong answer, it seems like it passes wthe wrong string...:(
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 8

Expert Comment

by:rajaloysious
ID: 13823734
LPCTSTR  should be used if you are passing a input only variable...
if source is input,
unsafe private static extern IntPtr GetHashHex([MarshalAs(UnmanagedType.LPCTSTR )] String source, [MarshalAs(UnmanagedType.U2)] System.UInt16 key);

if source is output
unsafe private static extern IntPtr GetHashHex([MarshalAs(UnmanagedType.LPTStr)] StringBuilder source, [MarshalAs(UnmanagedType.U2)] System.UInt16 key);

cheers
0
 

Author Comment

by:GiedriusS
ID: 13831200
the source is input,
there is no UnmanagedType.LPCTSTR..
i think that there should be used an array...
i tried:

unsafe private static extern IntPtr GetHashHex([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1] char[] source, [MarshalAs(UnmanagedType.U2)] System.UInt16 key);

the same result: does not work with large arrays:(
0
 
LVL 8

Expert Comment

by:rajaloysious
ID: 13832087
if you dont mind, can you post the code snippet so that i can have a look
the declaration of the function, the call of the function and decleration of the variables involved..

cheers
0
 

Author Comment

by:GiedriusS
ID: 13833040
the win32 dll source in delphi
------------------------------------------------------------------------------
library MSUtils;

uses
  ShareMem,
  SysUtils,
  Classes,
  CryptoApi,
  EncryptIt, Dialogs;

{$R *.res}

function HashString(Method: Integer; SourceStr: PChar; var DestStr: string): Integer;
var
  FHashResult: string;
begin
  try
    CryptoApi.HashStr(Method, SourceStr, FHashResult);
    Result := 0;
  except
    Result := -1;
  end;
  DestStr := FHashResult;
end;

function EncryptString(const S: string; Key: word): string;
begin
  Result := Encrypt(S, Key);
end;

function DecryptString(const S: string; Key: word): string;
begin
  Result := Decrypt(S, Key);
end;

function StrToHex(S: string): string; stdcall;
  function HexB(b: Byte): string;
  const
    HexChar: array[0..15] of char = '0123456789ABCDEF';
  begin
    HexB := HexChar[b shr 4] + HexChar[b and $0F];
  end;
var
  I: Integer;
begin
  Result := '';
  for I := 1 to Length(S) do
    Result := Result + HexB(Ord(S[I]));
end;

function HexToStr(HexS: string): string;
  function Str2Int(Str:string):integer;
  var temp,code : integer;
  begin
     if length(Str) = 0 then
        Str2Int := 0
     else
     begin
        val(Str,temp,code);
        if code = 0 then
           Str2Int := temp
        else
         raise EConvertError.Create('Bloga aritmetika');
     end;
  end; {Str2Int}

  function HEXStr2Int(Str: string):Integer;
  begin
     if Str = '' then
        HexStr2Int := 0
     else
     begin
        if Str[1] <> '$' then
           Str := '$'+Str;
        HexStr2Int := Str2Int(Str);
     end;
  end; {HexStr2Int}
var
  I: Integer;
  S: string;
begin
  Result := '';
  I := 1;
  repeat
    S := Copy(HexS, I, 2);
    I := I + 2;
    Result := Result + Chr(HexStr2Int(S)); //StrB(S);
  until I > Length(HexS);
end;

function GetHashHex(SourceStr: Array of Char; Key: word): PChar; stdcall;
var
  Hash: string;
  EHash: string;
  S: string;
begin
  HashString(HASH_MD2, SourceStr, Hash);
  EHash := EncryptString(Hash, Key);
  Result := PChar(StrToHex(EHash));
end;

exports
  StrToHex,
  GetHashHex;
{  HashString,
  EncryptString,
  DecryptString,
  HexToStr;}

begin
end.

my source in c# that works with small arrays....
------------------------------------------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Xml;
using System.IO;
using System.Reflection;
using System.Drawing.Printing;
using System.Runtime.InteropServices;

namespace MsBraiza
{
  public class MainForm : System.Windows.Forms.Form
  {
        [DllImport("MSUtils.dll")]
        unsafe private static extern IntPtr GetHashHex([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1)] char[] source, [MarshalAs(UnmanagedType.U2)] System.UInt16 key);

/// builds string, with a hex code instead of a character
private static String StrToHex(String s)
{
  String sRetString = "";
  char[] HexSym = new char[16]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  for (int i = 0; i < s.Length; i++)
  {
    sRetString += HexSym[(Byte)s[i] >> 4].ToString() + HexSym[(Byte)s[i] & 0x0F].ToString();
  }
  return sRetString;
}

    [STAThread]
    static void Main(String[] args)
    {
      String sFileContents = "";
      String sLine;
      StreamReader sr = new StreamReader(args[0]);
      for (;;)
      {
        sLine = sr.ReadLine();
        if (null == sLine)
          break;
        sFileContents += sLine + "\r\n";
      }
      sr.Close();
      String sRet = MainForm.StrToHex(sFileContents).ToLower();  // ~13Kb

      IntPtr ptr = GetHashHex(sRet.ToCharArray(), (ushort)61095);
      String sCheckHash = Marshal.PtrToStringAnsi(ptr);

     /// .... windows forms related code
    }
  }
}
0
 
LVL 8

Expert Comment

by:rajaloysious
ID: 13833714
Try changing
String sCheckHash = Marshal.PtrToStringAnsi(ptr);
to
String sCheckHash = Marshal.PtrToStringAuto(ptr);

Also try giving some value for the no of characters:
PtrToStringAuto (System.IntPtr ptr, int len)

The string may not be an ANSI string
check here and use any one of the PtrToStringXXX
http://www.go-mono.com/docs/index.aspx?link=M:System.Runtime.InteropServices.Marshal.PtrToStringAnsi

cheers
0
 

Author Comment

by:GiedriusS
ID: 13840404
i tried all, only ansi gives something right...
if i use auto or others i get many binary codes which are not letters, and in the case when i use large array it returns empty string:( because the function returns bad pointer.. (debuger that it's bad)
0
 
LVL 8

Accepted Solution

by:
rajaloysious earned 375 total points
ID: 13841159
If that is the case it really should be the limitation of the perl function.
Have you read the documentation of the perl function - Have a look at this too...http://www.dotnet247.com/247reference/msgs/45/228039.aspx
Apologies as this is the case

cheers
0
 

Author Comment

by:GiedriusS
ID: 13856908
i give up! that's impossible!
anyway thank you for your time..
rajaloysious
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering 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

This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Screencast - Getting to Know the Pipeline
Suggested Courses

868 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