开发者

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.

  1. Under Compatibility select "Allow unsafe code"
  2. Under Build, find the General Section and change CPU Type to "x86"
  3. 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;    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜