Почему пример UnManaged Export не работает в призме XE - PullRequest
2 голосов
/ 26 сентября 2011

Я пытаюсь скомпилировать Этот пример для неуправляемого экспорта в XE, но я получаю (PE9) Неизвестный идентификатор "UnmanagedExport" ошибка при сборке.

  1. В разделе «Совместимость» выберите «Разрешить небезопасный код»
  2. В разделе «Сборка» найдите общий раздел и измените тип процессора на «x86»
  3. Щелкните правой кнопкой мыши на созданной вкладке «ClassLibraryX» и выберите «Сохранить выбранные элементы»
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.

Окно ошибок

Есть идеи?

@ Дэвид: Спасибо за ответ. Я попробовал твой совет

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;

но та же ошибка продолжается.

@ Давид 2:):

Я изменил код следующим образом:

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.

Та же ошибка:)

@ Дэвид 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.

все та же ошибка. :, ( Можете ли вы примерить мне призму ide моего образца проекта для меня, пожалуйста? Спасибо за ответы.

    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

моя версия oxygene 4.0.25.791, я полагаю.

..............................

@ Дэвид: Я тоже пытался скомпилировать в командной строке. вот результаты

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\exptest>

вероятно, ваше право. возможно что-то не так с моим компилятором. Но я не увидел никакой ошибки во время установки призмы Delphi.

@ Руди: До этого меня судили VS2010. Как я сказал. Может быть, я переустановить Delphi Prism или попробовать другую машину. Я напишу результаты, если решите.

Ответы [ 3 ]

1 голос
/ 26 сентября 2011

Я думаю, что главная проблема в том, что вам нужно использовать пространство имен RemObjects.Oxygene.System, в котором определено UnmanagedExport.

На самом деле похоже, что uses не нужен (см. Ниже).


Вам также необходимо сделать метод методом класса.

[UnmanagedExport('xmsg',CallingConvention.StdCall)]
class function xmsg(amsg: String): String;

И аналогично в реализации.

Обратите внимание, что function и procedure устарели в Prism, и вместо них следует использовать method.

[UnmanagedExport('xmsg',CallingConvention.StdCall)]
class method xmsg(amsg: String): String;

Эта информация была получена из docwiki .


Я скачал компилятор командной строки для Prism XE. Это версия 4.0 и поэтому поддерживает атрибут UnmanagedExport.

Я успешно скомпилировал следующий блок:

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.

Вывод был:

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.

Это произвело DLL, которая, как я проверял, содержала одну экспортированную функцию с именем foo.

Затем я вызвал DLL из Python через ctypes:

>>> import ctypes
>>> lib = ctypes.WinDLL('test.dll')
>>> lib.foo()
666

Таким образом, я могу только сделать вывод, что ваша проблема не в коде. Возможно, у вас неправильно настроена установка Prism. Не могли бы вы повторить мою командную строку выше? Не могли бы вы выполнить переустановку Prism.

0 голосов
/ 07 мая 2012

Я решил проблему таким образом. 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;
      }



   }
}

И паскаль сторона

_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 голосов
/ 26 сентября 2011

Это работает для меня, используя Prism XE2 (5.0.29.893) в оболочке VS2010. Это, вероятно, не будет работать в версии ранее, чем 3.0.19 :

  • Начать новый проект - Библиотека классов
  • Переименовать в XClassLibrary и сохранить
  • установите параметры как вы (разрешить небезопасный код, цель x86)

Сделать код Class1 похожим на это:

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.

Затем Build> Build Solution.Я получаю успешную сборку:

------ 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 ==========
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...