473,327 Members | 2,081 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

Non-dotnet DLLs: brick wall hit

Hi,

I'm trying to find my feet with C# and have hit a bit of a wall.

I have lots of legacy code in a DLL written in Delphi. I don't think
the fact that it's written in Delphi should cause too much of a
problem since the code is just simple Pascal that does arithmetic and
string manipulations, and all "strings" in the structures passed to
and from the DLL are actually arrays of char.

I want to retain the DLL for use in existing applications, but also
make of it in C# applications. The routines need to be available and
maintainable for several applications, including legacy ones.

Anyway...

As a proof of concept, I want to be able to pass what should, to my
mind, be a simple structure (data to be processed) to the DLL and
return a simple structure (results) back to the calling C#
application. (I'm using the word "structure" to avoid being too
specific; I'm not even sure if I should use a struct or a class.)

I've spent ages trawling through newsgroups and tries all sorts of
examples of code but nothing seems to quite work. There are many
messages on this subject with lots of no-doubt useful advice, but I
think the advice will make more sense to me if I have a working
example to play with.

So, does anyone have a mickey-mouse example of passing and returning
"structures" (in my ill-defined sense) from a C# application to a
non-.NET DLL.

Thanks.

Gary Jones
(Please send any replies here rather than by email.)
Nov 16 '05 #1
10 2760
You can simply pass a pascal string as string, and pchar as StringBuilder to
the functions in your dll. Is that what you wanted to hear?
Maybe you could be a bit more specific.

"Gary Jones" <no**********@hotmail.com> schrieb im Newsbeitrag
news:1f**************************@posting.google.c om...
Hi,

I'm trying to find my feet with C# and have hit a bit of a wall.

I have lots of legacy code in a DLL written in Delphi. I don't think
the fact that it's written in Delphi should cause too much of a
problem since the code is just simple Pascal that does arithmetic and
string manipulations, and all "strings" in the structures passed to
and from the DLL are actually arrays of char.

I want to retain the DLL for use in existing applications, but also
make of it in C# applications. The routines need to be available and
maintainable for several applications, including legacy ones.

Anyway...

As a proof of concept, I want to be able to pass what should, to my
mind, be a simple structure (data to be processed) to the DLL and
return a simple structure (results) back to the calling C#
application. (I'm using the word "structure" to avoid being too
specific; I'm not even sure if I should use a struct or a class.)

I've spent ages trawling through newsgroups and tries all sorts of
examples of code but nothing seems to quite work. There are many
messages on this subject with lots of no-doubt useful advice, but I
think the advice will make more sense to me if I have a working
example to play with.

So, does anyone have a mickey-mouse example of passing and returning
"structures" (in my ill-defined sense) from a C# application to a
non-.NET DLL.

Thanks.

Gary Jones
(Please send any replies here rather than by email.)

Nov 16 '05 #2
On 04/01/2005 Gary Jones wrote:

So, does anyone have a mickey-mouse example of passing and returning
"structures" (in my ill-defined sense) from a C# application to a
non-.NET DLL.


Hi Gary

I suspect a lot of my code is 'Micky Mouse' :-)

Can you post the structure that the Delphi DLL expects and we can
probably explain how to re-create it in C#.
--
Jeff Gaines
Posted with XanaNews 1.17.1.2 http://www.wilsonc.demon.co.uk/delphi.htm
Nov 16 '05 #3
> You can simply pass a pascal string as string, and pchar as StringBuilder to
the functions in your dll. Is that what you wanted to hear?


I would be very very very surprised if he could pass a Delphi string as
a string in C#. Delphi string requires the link with the Borland lib
ShareMem in both projects (dll and calling app) to work.

--
----
http://michael.moreno.free.fr/

Nov 16 '05 #4
Yes you are right, delphi strings are not nullterminated strings like in
C++, my mistake. But you can pass pchar as StringBuilder, it is marshalled
automatically. And for the pascal string, you can pass it as a simple char
array, the char at index 0 will be the lenght of the string, this should
work without any problems.

"Michael Moreno" <mi*********************@free.fr> schrieb im Newsbeitrag
news:mn***********************@free.fr...
You can simply pass a pascal string as string, and pchar as StringBuilder to the functions in your dll. Is that what you wanted to hear?


I would be very very very surprised if he could pass a Delphi string as
a string in C#. Delphi string requires the link with the Borland lib
ShareMem in both projects (dll and calling app) to work.

--
----
http://michael.moreno.free.fr/

Nov 16 '05 #5
The structures I actually need to use are very large (around 200 data
items being passed into the DLL, and a similar number in the returned
structure), so I'm just trying to get a trivial example working in C#.
To test things, I've written a silly little Delphi DLL which works the
way I'm familiar with; it accepts two pointers: one to the data to be
processed, and the other to the results to be populated.

In Delphi, my example looks like this:

type
stringz255=array[0..255] of char;

TinData=record
i:integer;
s:stringz255;
end;

ToutData=record
i1,i2:integer;
s1,s2:stringz255;
end;

PinData=^TinData;
PoutData=^ToutData;
The declaration of the main routine in the DLL looks like this...
procedure dllCore(inData:PinData;outData:PoutData);cdecl;
.... and my main DLL routine looks like this...
procedure dllCore(inData:PinData;outData:PoutData);
var
workIn:TinData;
workOut:ToutData;
begin
// dereference
workIn:=inData^;
workOut:=outData^;

// do something useful here

// rereference
outData^:=workOut;
end;
My Delphi calling application looks like this...
procedure dllCore(inData:PinData;outData:PoutData);cdecl; external
'DLLexample.dll';

procedure TmainForm.doitBtnClick(Sender: TObject);
var
callIn:Tindata;
callOut:ToutData;
begin
// assign values in callIn

dllCore(@callIn,@callOut);

// do whatever with values in callOut
end;
The example DLL looks like it should be straightforward to use in C#,
but I've tried several approaches and am still struggling.

I have the Delphi source code in my real-world application, so can make
changes on that side if necessary to make things easier or more
elegant.

Thanks.
Gary Jones

(Using Google Groups to post here and have just discovered that I now
have to use the new Google Groups beta.)

Nov 16 '05 #6
Hello GaryJones,
The structures I actually need to use are very large (around 200 data
items being passed into the DLL, and a similar number in the returned
structure), so I'm just trying to get a trivial example working in C#.


You might consider making this Delphi project into a COM project using a Remote Data Module. If you reference the COM object in C# it will create a proxy class that's easy to use.

P-Invoke in C# to call Win32 style DLLs is a little harder. It can be done, of course, but the RDM option is the easiest.
Nov 16 '05 #7
On 04/01/2005 GaryJones wrote:
The structures I actually need to use are very large (around 200 data
items being passed into the DLL, and a similar number in the returned
structure), so I'm just trying to get a trivial example working in C#.
To test things, I've written a silly little Delphi DLL which works the
way I'm familiar with; it accepts two pointers: one to the data to be
processed, and the other to the results to be populated.


I installed D7 to try and build your dll but it just reminded me of all
the reasons I gave up on Delphi :-(

The following works in a C# app:

struct TinData
{
public int i;
public StringBuilder s;
}

struct ToutData
{
public int i;
public StringBuilder s;
}

private void dllCore(ref TinData tin, ref ToutData tout)
{
tout.i = tin.i;
tout.s = tin.s;
}

private void btnTest_Click(object sender, System.EventArgs e)
{
JTest();
}

private void JTest()
{
TinData tinTemp = new TinData();
tinTemp.i = Convert.ToInt32(txti.Text);
tinTemp.s = new StringBuilder();
tinTemp.s.Append(txts.Text);

ToutData toutTemp = new ToutData();
toutTemp.s = new StringBuilder();

dllCore(ref tinTemp, ref toutTemp);

lbli.Text = toutTemp.i.ToString();
lbls.Text = toutTemp.s.ToString();
}

However it may be meaningless when it meets the dll!

I put together a test Form which has TextBoxes txti and txts, Labels
lbli and lbls and a Button btnTest.

By passing the two data structures as 'ref' they are effectively
pointers but I'm not sure how Delphi will react?

If you want to post the dll or its source I am happy to have a play, or
perhaps somebody else will pop in with some ideas.
--
Jeff Gaines
Posted with XanaNews 1.17.1.2 http://www.wilsonc.demon.co.uk/delphi.htm
Nov 16 '05 #8
> The declaration of the main routine in the DLL looks like this...
procedure dllCore(inData:PinData;outData:PoutData);cdecl;


I may well be wrong about this, but I thought that functions to be called
through PInvoke had to use the stdcall calling convention (rather than
cdecl).

Chris Jobson
Nov 16 '05 #9
Chris,

stdcall is the default, you can change this default by means of the
"CallingConvention" DllImportAttribute member.

Willy.

"Chris Jobson" <ch**********@btinternet.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
The declaration of the main routine in the DLL looks like this...
procedure dllCore(inData:PinData;outData:PoutData);cdecl;


I may well be wrong about this, but I thought that functions to be called
through PInvoke had to use the stdcall calling convention (rather than
cdecl).

Chris Jobson

Nov 16 '05 #10
Chris Jobson <ch**********@btinternet.com> wrote:
The declaration of the main routine in the DLL looks like this...
procedure dllCore(inData:PinData;outData:PoutData);cdecl;


I may well be wrong about this, but I thought that functions to be called
through PInvoke had to use the stdcall calling convention (rather than
cdecl).


You can specify either using the CallingConvention member of
DllImportAttribute. I haven't used it myself, but it looks like it
should be able to do the job.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: klaus triendl | last post by:
hi, recently i discovered a memory leak in our code; after some investigation i could reduce it to the following problem: return objects of functions are handled as temporary objects, hence...
3
by: Mario | last post by:
Hello, I couldn't find a solution to the following problem (tried google and dejanews), maybe I'm using the wrong keywords? Is there a way to open a file (a linux fifo pipe actually) in...
25
by: Yves Glodt | last post by:
Hello, if I do this: for row in sqlsth: ________pkcolumns.append(row.strip()) ________etc without a prior:
32
by: Adrian Herscu | last post by:
Hi all, In which circumstances it is appropriate to declare methods as non-virtual? Thanx, Adrian.
8
by: Bern McCarty | last post by:
Is it at all possible to leverage mixed-mode assemblies from AppDomains other than the default AppDomain? Is there any means at all of doing this? Mixed-mode is incredibly convenient, but if I...
14
by: Patrick Kowalzick | last post by:
Dear all, I have an existing piece of code with a struct with some PODs. struct A { int x; int y; };
11
by: ypjofficial | last post by:
Hello All, So far I have been reading that in case of a polymorphic class ( having at least one virtual function in it), the virtual function call get resolved at run time and during that the...
2
by: Ian825 | last post by:
I need help writing a function for a program that is based upon the various operations of a matrix and I keep getting a "non-aggregate type" error. My guess is that I need to dereference my...
399
by: =?UTF-8?B?Ik1hcnRpbiB2LiBMw7Z3aXMi?= | last post by:
PEP 1 specifies that PEP authors need to collect feedback from the community. As the author of PEP 3131, I'd like to encourage comments to the PEP included below, either here (comp.lang.python), or...
12
by: puzzlecracker | last post by:
is it even possible or/and there is a better alternative to accept input in a nonblocking manner?
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.