Why UnManaged Export example is doesnt work in prism XE
I'm trying to compile This Example for unmanaged export in XE but I getting (PE9) Unknown identifier "UnmanagedExport" error when build.
- Under Compatibility select "Allow unsafe code"
- Under Build, find the General Section and change CPU Type to "x86"
- Right Click on the "ClassLibraryX" tab that was created and select "Save selected Items"
namespace exptest; interface uses System.Runtime.InteropServices; type clstest = public static class private protected public [UnmanagedExport('xmsg',CallingConvention.StdCall)] function xmsg(amsg : String):String; end; implementation function clstest.xmsg(amsg: String):String; Begin Result := amsg + ' mesajı için geri dönüş'; end; end.
Error Window
Any idea?
@David:Thanks for answer. I've tried your tip
public
[UnmanagedExport('xmsg',CallingConvention.StdCall)]
class method xmsg(amsg : String):String;
end;
implementation
class method clstest.xmsg(amsg: String):String;
Begin
Result := amsg + ' mesajı için geri dönüş';
end;
but same error is continues.
@David 2 :):
I've changed code in this way:
namespace exptest;
interface
uses
RemObjects.Oxygene.System;
type
clstest = public class
private
protected
public
[UnmanagedExport('xmsg',CallingConvention.StdCall)]
class method xmsg(amsg : String):String;
end;
implementation
class method clstest.xmsg(amsg: String):String;
Begin
Result := amsg + ' mesajı için geri dönüş';
end;
end.
Same error :)
@david 3
namespace exptest;
interface
uses
RemObjects.Oxygene.System,System.Runtime.InteropServices;
type
clstest = public class
private
protected
public
[UnmanagedExport('xmsg',CallingConvention.StdCall)]
class method xmsg(amsg : String):String;
end;
implementation
class method clstest.xmsg(amsg: String):String;
Begin
Result := 'a return value for '+amsg ;
end;
end.
still same error. :,( Can you try on your prism ide my sample project for me please? Thanks for answers.
C:\Program Files\Embarcadero\Delphi Prism\bin>oxygene -version
RemObjects Oxygene for .NET - Version 4.0.25.791
Copyright RemObjects Software 2003-2009. All rights reserved.
Exclusively licensed for Delphi Prism.
Configuration Release not found
my oxygene version 4.0.25.791 I suppose.
..............................
@David: I tried compile on command line too. here is results
C:\Documents and Settings\XPMUser\Desktop\exptest\exptest>oxygene /allowunsafe:y
es /type:library /cputype:x86 clstest.pas
RemObjects Oxygene for .NET - Version 4.0.25.791
Copyright RemObjects Software 2003-2009. All rights reserved.
Exclusively licensed for Delphi Prism.
Preparing resources...
Compiling...
C:\Documents and Settings\XPMUser\Desktop\exptest\exptest\clstest.pas(14,22) :
Error : (PE9) Unknown identifier "UnmanagedExport"
Exiting with 1.
C:\Documents and Settings\XPMUser\Desktop\exptest\e开发者_Python百科xptest>
probably your right. maybe something wrong with my compiler. But i didnt see any error during install Delphi prism.
@Rudy: I was tried VS2010 ide before this. As I Said. Maybe i reinstall delphi prism or try different machine. I'll write results if solve.
I think the main problem is that you need to use the RemObjects.Oxygene.System
namespace which is where UnmanagedExport
is defined.
In fact it looks like that uses
is not needed (see below).
You also need to make the method a class method.
[UnmanagedExport('xmsg',CallingConvention.StdCall)]
class function xmsg(amsg: String): String;
And likewise in the implementation.
Note that function
and procedure
are deprecated in Prism and you should use method
instead.
[UnmanagedExport('xmsg',CallingConvention.StdCall)]
class method xmsg(amsg: String): String;
This information was gleaned from the docwiki.
I downloaded the command line compiler for Prism XE. This is version 4.0 and so supports the UnmanagedExport
attribute.
I successfully compiled the following unit:
namespace ExportTest;
interface
uses
System.Runtime.InteropServices;
type
test = class
[UnmanagedExport('foo', CallingConvention.StdCall)]
class method foo: Integer;
end;
implementation
class method test.foo: Integer;
begin
Result := 666;
end;
end.
The output was:
C:\Desktop>oxygene /allowunsafe:yes /type:library /cputype:x86 test.pas
RemObjects Oxygene for .NET - Version 4.0.25.791
Copyright RemObjects Software 2003-2009. All rights reserved.
Exclusively licensed for Delphi Prism.
Preparing resources...
Compiling...
Compile complete.
This produced a DLL which I verified contained a single exported function named foo
.
Next I called the DLL from Python via ctypes:
>>> import ctypes
>>> lib = ctypes.WinDLL('test.dll')
>>> lib.foo()
666
Thus I can only conclude that your problem is not with the code. You perhaps have a mis-configured Prism installation. Could you try to repeat my command line above? Could you perform a re-installation of Prism.
This works for me, using Prism XE2 (5.0.29.893) in the VS2010 Shell. This probably won't work in a version earlier than 3.0.19:
- Start a new project - Class Library
- Rename to XClassLibrary and save
- set options as you did (allow unsafe code, x86 target)
Make the code of Class1 look like this:
namespace XClassLibrary;
interface
uses
System.Runtime.InteropServices;
type
Class1 = public class
private
protected
public
[UnmanagedExport('xmsg', CallingConvention.StdCall)]
class method xmsg(aMsg: String): String;
end;
implementation
class method Class1.xmsg(aMsg: string): string;
begin
Result := aMsg + ' plus some Turkish text';
end;
end.
Then Build > Build Solution. I get a successful build:
------ Build started: Project: XClassLibrary, Configuration: Debug ------
XClassLibrary -> c:\users\administrator\documents\visual studio 2010\Projects\XClassLibrary\XClassLibrary\bin\Debug\XClassLibrary.dll
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
I Solved problem this way. RGiesecke.DllExport
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
using System.IO;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Configuration;
namespace thenamespace
{
{
private static some_members
...
...
...
[DllExport(CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPStr)]
static String GetValue(
[MarshalAs(UnmanagedType.LPStr)] String _url,
[MarshalAs(UnmanagedType.LPStr)] String _username,
[MarshalAs(UnmanagedType.LPStr)] String _password,
int _method,
[MarshalAs(UnmanagedType.LPStr)] String _identid,
int _isTestMode,
int _TimeOutAsSecond,
[MarshalAs(UnmanagedType.LPStr)] String _ProxyAddr,
[MarshalAs(UnmanagedType.LPStr)] String _ProxyUsername,
[MarshalAs(UnmanagedType.LPStr)] String _ProxyPassword)
{
...
return result;
}
}
}
And pascal side
_fGetValue = function(_url, _username, _password: pAnsiChar; _method: Integer;
_identid: pAnsiChar; _isTestMode : Integer; _TimeOutAsSecond:Integer;
_ProxyAddr:PAnsiChar;_ProxyUsername:PAnsiChar;_ProxyPassword:PAnsiChar): pAnsiChar; stdcall;
...
...
...
var
dllHandle: cardinal;
dllFunc: _fGetValue;
__url, __username, __password, __tckimlik, __result: pAnsiChar;
__metod: Integer;__ProxyAddr:PAnsiChar;
__ProxyUsername:PAnsiChar;__ProxyPassword:PAnsiChar;
begin
Result := '';
__result := '';
dllHandle := LoadLibrary('thelib.dll');
If dllHandle <> 0 then
begin
dllFunc := nil;
@dllFunc := GetProcAddress(dllHandle, 'GetValue');
if Assigned(dllFunc) then
__result := dllFunc(__url, __username, __password, __metod, __identid,
_isTestMode,_TimeOutAsSecond,__ProxyAddr,__ProxyUsername,__ProxyPassword)
else
Begin
raise Exception.Create('Method is not found');
End;
Result := __result;
FreeLibrary(dllHandle);
end
else
begin
raise Exception.Create('Library not found thelib.dll');
end;
end;
精彩评论