Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> портирование кода на delphi в С++ 
:(
    Опции темы
2faust
Дата 10.7.2008, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 14.12.2005

Репутация: нет
Всего: нет



здавствуте уважаемые люди.  smile 
в этот разделе мне пришлось обратиться по незнанию языка делфи и в надежде на то, что кто-то из нающих людей делфи и С/С++ поможет решить следующую проблему.
имется утилита, которая написана на делфи и подключается к dll, при попытке переписать ее на С++/MFC меня постигла небольшая проблемма, а именно при компиляции моей программы ошибок не возникает, а вот при первом вызове ф-ции из dll выскакивает ошибка, которую я увы,в силу сложившихся обстоятельств решить не могу пока.
dll сама не докуметирована, но у один умный человек сумел написать утилиту, которая умеет обращаться к ф-циям из dll.

ниже привожу код:
Код



type

  TMainform = class(TForm)
  ...
   
 private
    { Private declarations }
    procedure UpdateStats;
    function GetRealName(num: byte; AdapterName: String): String;
    ...
 
  TDVBName = Array [1..4000] of char;
  
  TTunerStatus = record
   freq : DWORD;            
   lof  : DWORD;        
   sr   : DWORD;         
   fec  : DWORD;        
   pol  : DWORD;         
   lnb_switch   : DWORD; 
   diseqc       : DWORD;
   ...
   end;

  PTunerStatus = ^TTunerStatus;
  
  var
  Mainform: TMainform;
  DVBName : TDVBName;
  DVBName2: TDVBName;

  hlib : THANDLE;       // SkyDll.dll
  SkyUIlib : THandle;   // Sky2PCUI.dll

  pSkyOpen : Pointer;
  hSkyAdapter : DWORD;
  res : Integer;
  TunerStatus : TTunerStatus;
  TunerCaps   : TTunerCapabilities;
 
 // SkyDll.dll
  SkyOpen       : function (Name : TDVBName): Integer; cdecl;
  SkyClose      : function : Integer; cdecl;
  SkyAdapterGetHandle   : function (int : Byte; pSkyAdapter : PDWORD): Integer; cdecl;
  SkyAdapterGetName     : function (int : Byte; SkyAdapterNameCLSID : TDVBName): Integer; cdecl;
  SkyAdapterTunerGet    : function (hSky :DWORD; TunerStatus: PTunerStatus; sizeTS: Integer): Integer; cdecl;
  SkyAdapterTunerSet    : function (hSky :DWORD; TunerStatus: PTunerStatus; sizeTS: Integer): Integer; cdecl;
  SkyGetNumAvailAdapters        : function (num : PDWORD) : Integer; cdecl;
  ...

implementation

procedure TMainform.FormShow(Sender: TObject);
var
        i, num : DWORD;
        AdapterNameStr: String;
begin
        hlib := LoadLibrary('SkyDll.dll');

        @SkyOpen := GetProcAddress(hlib, 'SkyOpen');
        @SkyClose := GetProcAddress(hlib, 'SkyClose');
        @SkyAdapterGetHandle := GetProcAddress(hlib, 'SkyAdapterGetHandle');
        @SkyAdapterGetName := GetProcAddress(hlib, 'SkyAdapterGetName');
        @SkyAdapterTunerGet := GetProcAddress(hlib, 'SkyAdapterTunerGet');
        @SkyGetNumAvailAdapters := GetProcAddress(hlib, 'SkyGetNumAvailAdapters');

        fillchar(DVBName, sizeof(DVBName), 0);

        res := SkyOpen(DVBName);
        if res = 0 then lb_debug.items.add('Device started successfully.');
        AdapterNameStr:= 'DVBName : [';
        i:=1;
        while DVBName[i] <> chr(0) do
        begin
         AdapterNameStr:= AdapterNameStr + DVBName[i];
         inc(i);
        end;
        AdapterNameStr:= AdapterNameStr + ']';
        lb_debug.items.add(AdapterNameStr);

        // Get Number of Cards
        res := SkyGetNumAvailAdapters(@num);
        if num > 0 then
         lb_debug.items.add('Available Adapters Count :' + inttostr(num));

        res := SkyAdapterGetHandle(0, @hSkyAdapter);
        if res = 0 then
        lb_debug.items.add('AdapterHandle is :' + inttostr(hSkyAdapter));

        fillchar(DVBName,sizeof(DVBName),0);
        res := SkyAdapterGetName(0, DVBName);
        if res = 0 then
        begin
         AdapterNameStr := '';
         i:=1;
         while DVBName[i] <> chr(0) do
         begin
          AdapterNameStr:= AdapterNameStr + DVBName[i];
          inc(i);
         end;
         lb_debug.items.add('Adapter Name is : ' + GetRealName(0, AdapterNameStr));
         lb_debug.items.add('Drivers Version : ' + GetRealName(1, AdapterNameStr));
        end;
        UpdateStats;

end;



я не прошу переписывать весь код, мне бы хотя бы описание кода до третьего вызова ф-ции из dll.
если есть необходимость, могу выложить переписанный мной код на С++.

PM MAIL   Вверх
Rennigth
Дата 10.7.2008, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



2faust, покажи что у тебя на сях получилось.


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
2faust
Дата 10.7.2008, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 14.12.2005

Репутация: нет
Всего: нет



привожe некоторые строки из моего кода:
Код


#define uint unsigned int
#define ulong unsigned long
#define byte /*unsigned*/ char

#ifndef __SS2TUNERSTATUS__
#define __SS2TUNERSTATUS__
 

struct SS2TunerStatus
{
    /*uint*/DWORD freq;
    /*uint*/DWORD lof;
    /*uint*/DWORD sr;
  ....
}

#endif

/* SkyDll.h */
#include "SS2TunerStatus.h"

#ifndef __SKYDLL_H
#define __SKYDLL_H

    extern "C" __declspec(dllimport) typedef  int (__stdcall SkyOpen)(byte*) ;     
    extern "C" __declspec(dllimport) typedef  int (__stdcall SkyClose)();
    extern "C" __declspec(dllimport) typedef  int (__stdcall SkyAdapterGetHandle)(int,/*int**/DWORD);
    extern "C" __declspec(dllimport) typedef int (__stdcall SkyAdapterGetName)(int,byte[]);
   ....
#endif

/* ConsoleDlg.cpp*/
#include "stdafx.h"
#include "SDK.Demo.Console.h"
#include "SDK.Demo.ConsoleDlg.h"
#include "SkyDll.h"

CConsoleDlg::CConsoleDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CConsoleDlg::IDD, pParent) 
    ,SIZE_OPENSTREAM(0x160)                     /* 0x160  = 352  byte */
    ,SIZE_STREAMDATA(0x20)                     /* 0x20   = 32   byte */
    ,SIZE_PIDMASK(0xA0)                     /* 0xA0   = 160  byte */
    ,SIZE_PIDMASKEXTRA(0x5A)                 /* 0x5A   = 90  byte */
    ,SIZE_LOCKAUTHORIZATION(0x14)                         /* 0x14    = 20  byte */

{...}

BOOL CConsoleDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    ...

    hSkyOpen                        = NULL;
    hSkyClose                        = NULL;
    hSkyAdapterGetHandle                    = NULL;
    hSkyAdapterGetName                    = NULL;
  ...
  
    /* загружаем Dll */
    hSkyDll = LoadLibrary(_T("SkyDll.dll"));

    /* проверяем успешность загрузки */
    ASSERT( hSkyDll);                       
    if (hSkyDll==NULL)
    {
        MessageBox(_T("Error Load SkyDll.dll"),_T("Error"),MB_OK);
        InfoOut();        
    }

    /* пытаемся получить адрес функции SkyOpen */
    (FARPROC&)hSkyOpen=GetProcAddress((HMODULE)hSkyDll,"SkyOpen");
    ASSERT( hSkyOpen);
    if(hSkyOpen==NULL)
    {
        MessageBox(_T("Error Open SkyOpen()"),_T("Error"),MB_OK);
        InfoOut();
    }

    (FARPROC&)hSkyClose=GetProcAddress(hSkyDll,"SkyClose");
    ASSERT(hSkyClose);
    if(hSkyClose==NULL)
    {
        MessageBox(_T("Error Open SkyClose()"),_T("Error"),MB_OK);
        InfoOut();
    }

    (FARPROC&)hSkyAdapterGetHandle=GetProcAddress(hSkyDll,"SkyAdapterGetHandle");
    ASSERT(hSkyAdapterGetHandle);
    if(hSkyAdapterGetHandle==NULL)
    {
        MessageBox(_T("Error Open SkyAdapterGetHandle()"),_T("Error"),MB_OK);
        InfoOut();
    }
    ....
    
    ss2name =new char[4000];
  lockData = new int[SIZE_LOCKAUTHORIZATION];    
  
    return TRUE;  
} // & OnInitDialog() 

void CConsoleDlg::OnBnClickedButton1_Start()
{
    // TODO: Add your control notification handler code here
    Open();
    StartStreamAll();

}

bool CConsoleDlg::Open(void)
{
    CString tmp, tmp2, tmp3;
    int x=0;
    //TCHAR* t_ss2name;

    int* openStream = new int[SIZE_OPENSTREAM];
    int* streamData = new int[SIZE_STREAMDATA];
    int* pidMask = new int[SIZE_PIDMASK];
    DWORD* pidMaskExtra = new DWORD[SIZE_PIDMASKEXTRA*2];

    *ss2name = '\0';
    //FillMemory(ss2name,sizeof(ss2name),0);
    if (hSkyOpen(ss2name) == 0)
    {
        MessageBox(_T(" SkyOpen() started successfully. "),_T("Info"),MB_OK);
    }

    // Setup Video PID
    pidMaskExtra[0] = /*0x400*/1024;
    pidMaskExtra[2] = 1;
    pidMaskExtra[4] = /*(short)pid1.GetSel()*/163;  // Pid to set
    pidMaskExtra[43] = 1;          // enable
    hSkyAdapterMaskPidSetExtra(this->hSkyAdapter, pidMaskExtra, SIZE_PIDMASKEXTRA);

    // Setup Audio PID
    pidMaskExtra[0] = /*0x400*/1024;
    pidMaskExtra[2] = 1;
    pidMaskExtra[4] = /*(short)pid2.GetSel()*/92;  // Pid to set
    pidMaskExtra[43] = 1;          // enable
    hSkyAdapterMaskPidSetExtra(this->hSkyAdapter, pidMaskExtra, SIZE_PIDMASKEXTRA);

    x=hSkyAdapterGetHandle(0,_deviceHandle);
    if(x==0)
    {
        tmp.Format(_T("AdapterHandle is : %d "),_deviceHandle);
        MessageBox(tmp,_T("AdapterHandle"),MB_OK);
    }

    x=hSkyGetNumAvailAdapters(_deviceHandle);
    if(x>0)
    {
        tmp.Format(_T("Available Adapters Count : %d "),_deviceHandle);
        MessageBox(tmp,_T("Adapters Count"),MB_OK);    
    }
    
    //CWnd* pEdit = GetDlgItem(IDC_OUT_WINDOW);
    MessageBox(_T("Device started successfully."), _T("SkyStar2"),MB_OK);
    
    this->_ss2DriverName = ss2name;/*.Replace("\0", "")*/;
    //t_ss2name = (TCHAR*)ss2name;
    //tmp.Format("%s",t_ss2name);
    //this->_ss2DriverName = tmp;
    tmp = "Driver Name : ["; 
    tmp += this->_ss2DriverName; 
    tmp += "]";
    MessageBox(tmp,_T("SkyStar2"),MB_OK);
    ...
}


у меня возникла некоторая проблема при вызове ф-ции из dll.
По синтиксису проблем с компиляцией нету, а вот при вызове ф-ции из dll возникаеет ошика, которая оиписана:
First-chance exception at 0x00dd15c7 (FlyDll.dll) in MyConsole.exe: 0xC0000005: Access violation writing location 0xef349258.

Это сообщение отредактировал(а) 2faust - 10.7.2008, 12:36
PM MAIL   Вверх
Rennigth
Дата 10.7.2008, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



2faust, 
У вас в делфях функции объявляются с соглашением передачи параметров как cdecl, в приведенном вами куске кода на Сях они объявляются как stdcall. Вероятно в этом причина ошибки.

Это сообщение отредактировал(а) Rennigth - 10.7.2008, 13:39


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
2faust
Дата 10.7.2008, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 14.12.2005

Репутация: нет
Всего: нет



я вас конечно понимаю, но если бы все так было просто, я не оставлял бы сообщение на форуме. smile 
вызовы _cdecl на _sdcall и обратно перепробованы.

отвечать желательно с примерами,  smile и не односложно.
PM MAIL   Вверх
Rennigth
Дата 10.7.2008, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



2faust, 
А с чего примеры тебе делать? Кода всего ничего, dll самой нету, проверять не начем...  smile 


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
2faust
Дата 10.7.2008, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 14.12.2005

Репутация: нет
Всего: нет



окей.
могу сбросить весь код на делфи и мой код.
могу сбросить и саму dll для эксперемента.

проблем нету. smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0719 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.