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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> перевести код с С на дельфи, многих уже достало наверное 
:(
    Опции темы
Unregistered
Дата 1.11.2006, 04:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте.Вот код длл-ки написанной на С++. Нужна помощь в переводе на Дельфи.
dataserv2.h
Код

#ifndef DATASERV_H
#define DATASERV_H //включить только один раз


//--- Описания структур, используемых для общения с OPC-сервером ---//


#include <string.h>

#pragma pack(push, 1) // Важно!!! Байтовое выравнивание

//---------- Наименование  тега -----------//


struct TTagName
{
  char *name; // собственно наименование

  enum{QualityUsed=0x80000000, QualityGood=0x800000c0, QualityBad=0x80000000};

  TTagName(){name=NULL;};
  ~TTagName() {delete name; name = NULL;};

  void setName( const char *aName )
    {
    delete name;
    if( !aName ) 
        { name = 0; return; };
    name = new char[ strlen( aName ) + 1 ];
    if(name)
      strcpy(name, aName );
    };
};


//----------------------- Аналоговый тег ------------------------//
struct TAnTag : TTagName
{
  float value; // значение параметра в единицах физической величины
  unsigned int OpcQuality;
  TAnTag(){value=0;OpcQuality=0;}
};


//----------------------- Битовый тег ------------------------//
struct TBitTag : TTagName
{
  unsigned char value; // значение параметра (0 или 1)
  unsigned int OpcQuality;
  TBitTag(){value=0;OpcQuality=0;}
};

//----------------------- Целый тег ------------------------//


struct TIntTag : TTagName
{
  int value; // значение параметра 
  unsigned int OpcQuality;
  TIntTag(){value=0;OpcQuality=0;};
};

//----------------- Данные для OPC-сервера --------------------//
struct TDataForOPCServer
{
  unsigned char dataIsValid;   // признак того, что данные корректны
  unsigned short anTagsQnty;   // количество аналоговых тегов
  const TAnTag *anTagsArray;   // указатель на массив аналоговых тегов
  unsigned short bitTagsQnty;  // количество битовых тегов
  const TBitTag *bitTagsArray; // указатель на массив битовых тегов
  unsigned short intTagsQnty;  // количество целых тегов
  const TIntTag *intTagsArray; // указатель на массив целых тегов

  unsigned short structVersionNumber

  char DeviceName[64]; // имя устройства
  char Reserved[128]; // Зарезервировано для будущих модификаций.
                      // (эта память должна быть обнулена)
};


//=============== Функции, вызываемые OPC-сервером: ==============

extern "C"
{

//  1) функция, возвращающая указатель на блок объектовых данных
__declspec( dllexport )
     const TDataForOPCServer * PASCAL GetDataForOPCServer( void );

//   2) функция для изменения значения аналогового тега
__declspec( dllexport )
       unsigned char PASCAL SetAnTagValue(
       unsigned  number, 
       float value           
       );

//   3) функция для изменения значения битового тега
__declspec( dllexport )
       unsigned char PASCAL SetBitTagValue(
       unsigned  number, 
       unsigned char value  
       );

//   4) функция для изменения значения целого тега
__declspec( dllexport )
       unsigned char PASCAL SetIntTagValue(
       unsigned  number, 
       int value    
       );

__declspec( dllexport )
       void PASCAL OnShutDown();
}; // end of extern "C"

#pragma pack(pop) // restore origiunal alignment

#endif

В этом коде мне ничего не понятно.

dataserv2.cpp
Код

#include <windows.h>
#include "dataserv2.h"  // structure version # 2 !!!
#include "opc_codes.h"  
#include <math.h>
#include <process.h>
#include <stdio.h>

#define MAX_TAG 5 

TAnTag AnTag[MAX_TAG*2];
TBitTag BitTag[MAX_TAG*2];
TIntTag IntTag[MAX_TAG*2];

// структура, рассказывающая OPC-серверу, где находятся массивы тегов...

TDataForOPCServer DataForOpc[3]=
{
  {     1,
        MAX_TAG,AnTag,
        MAX_TAG,BitTag,
        MAX_TAG,IntTag, 
        2,  
        "Device1"
  },
  {     1,
        MAX_TAG,AnTag+MAX_TAG,
        MAX_TAG,BitTag+MAX_TAG,
        MAX_TAG,IntTag+MAX_TAG,
        2,    
        "Device2"
  },
  {0}
};
// ... и функция, возвращающая OPC-серверу указатель на эту структуру:


__declspec( dllexport )
const TDataForOPCServer * PASCAL GetDataForOPCServer()
{
  return DataForOpc;
};


//===  Функции изменения тегов разного типа: ==================

//    функция для изменения значения аналогового тега

__declspec( dllexport )
unsigned char PASCAL SetAnTagValue(
       unsigned num, 
       float value            // новое значение параметра
    )

  unsigned short device_no=HIWORD(num);
  unsigned short number=LOWORD(num);

  if(number<0 || number>=MAX_TAG || device_no>1)
      return FALSE;
  AnTag[device_no*MAX_TAG+number].value=value;

    
  return TRUE;
};

//---------------------------------------------------------------------------
//    функция для изменения значения битового тега

__declspec( dllexport )
unsigned char PASCAL SetBitTagValue(
       unsigned num, 
       unsigned char value    // новое значение параметра
       )
  unsigned short device_no=HIWORD(num);
  unsigned short number=LOWORD(num);

  if(number<0 || number>=MAX_TAG || device_no>1) 
      return FALSE;
  BitTag[device_no*MAX_TAG+number].value=value;
    
  return TRUE;
};

//---------------------------------------------------------------------------
//    функция для изменения значения целого тега

__declspec( dllexport )
unsigned char PASCAL SetIntTagValue(
       unsigned num, 
       int value    // новое значение параметра
       )
  unsigned short device_no=HIWORD(num);
  unsigned short number=LOWORD(num);

  if(number<0 || number>=MAX_TAG || device_no>1)
      return FALSE;
  IntTag[device_no*MAX_TAG+number].value=value; 
    
  return TRUE;
};

//---------------------------------------------------------------------------

float Dt= (float)0.003;
float Tt;

// Главная рабочая нить  DLL, в которой должен происходить опрос
// устройства и обновление значений в массивах тегов:

void WorkingThread( void *dummy ) // Thread function
{
  while(1)
  { int i;
    if(IntTag[0].value>0)
      Sleep(IntTag[0].value);
    else Sleep(10);
      

    Tt=Tt+Dt;
    if(Tt>10)
      Tt=Tt-(float)3.1415926*3;

    /*
    for(int k=0;k <2 ; k++) // simulate good/bad
        if(Tt<5)
             DataForOpc[k].dataIsValid=1;
        else DataForOpc[k].dataIsValid=0;
    */

    for(i=1; i != MAX_TAG; i++)  
    {
      // симулируем изменение значений:
      AnTag[i].value= (float)sin(Tt+i);
                 // structure version # 2 !!!:
      AnTag[i].OpcQuality= (AnTag[i].value<0.8)? TTagName::QualityUsed | OPC_QUALITY_GOOD : 
                                               TTagName::QualityUsed | OPC_QUALITY_LAST_USABLE;

      BitTag[i].value= (AnTag[i].value>0)? 1:0;
                 // structure version # 2 !!!:
      BitTag[i].OpcQuality= (AnTag[i].value<0.6)? TTagName::QualityGood : TTagName::QualityBad;

      IntTag[i].value= (int)(AnTag[i].value * 10);
                  // structure version # 2 !!!:
      IntTag[i].OpcQuality= (AnTag[i].value<0.7)? TTagName::QualityGood :
                                                TTagName::QualityUsed | OPC_QUALITY_COMM_FAILURE;
    };
  };
};


//---------------------------------------------------------------------------
// Класс, конструктор которого запускает рабочую нить DLL
// (это можно делать и из DLLEntryPoint по DLL_PROCESS_ATTACH,
// но через конструктор объекта, кажется, удобнее)

class MyWorkingThread
{
 public:

  MyWorkingThread() // Все делает конструктор:
  {

    // Заполняем массив имен тегов для OPC-сервера:
    for(int i=0; i != MAX_TAG*2; i++) // --v.2.0!
                // *2 - для обоих устройств !!!
    {
     char s[64]="";
     char ss[64]="";
     char sss[64]="";

     char* prefix= (i<MAX_TAG/2)? "unit1." : "unit2.";

     sprintf(s,"%sanalog_%d",prefix,i);
     sprintf(ss,"%sbit_%d",prefix,i);
     sprintf(sss,"%sint_%d",prefix,i);
     AnTag[i].setName(s);
     BitTag[i].setName(ss);
     IntTag[i].setName(sss);

     if(i==0) //в нашем примере 0-й целый тег управляет периодом обновления
              // данных в dll - ему даем специальное имя
     {
        IntTag[i].setName("UpdateRate");
        IntTag[i].value=10;// начальное значение

     };
        

    };
    // Создаем рабочую нить:
    _beginthread( WorkingThread, 0, NULL );
  };
};

//=========================================================

/* 
   инициализация статического объекта, конструктор которого 
   сразу после загрузки DLL создает рабочую нить
   (чтобы не возиться с DLLEntryPoint - хотя это, конечно,
   дело разработчика):
*/
MyWorkingThread* mythread=new MyWorkingThread;


Содержимое функций dataserv2.cpp мне более менее понятно. Его переводить не надо. По нему у меня другие вопросы. Куда писать процедуру WorkingThread, что у нее за параметр? Создавать поток или он не нужен? Использовать класс как предлагается выше не хочу, буду работать в DLLEntryPoint. Я пытался сам перевести этот код, но из-за незнания типов и синтаксиса С ничего не добился. Точнее добился (AV).  Буду очень признателен за помощь.  Спасибо.

PS. Код во вложенном архиве

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  Project.rar 7,04 Kb
PM MAIL   Вверх
Quadr0
Дата 1.11.2006, 08:17 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











...

Это сообщение отредактировал(а) Quadr0 - 15.7.2011, 13:15
  Вверх
Unregistered
Дата 1.11.2006, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо. А что на счет заголовочного файла? в частности: в объявлении структуры TTagName, содержится еще и функция? Ну и вообще по типам переменных...
как правильно объявить экспортируемую функцию:
__declspec( dllexport )
     const TDataForOPCServer * PASCAL GetDataForOPCServer( void );

я так пробовал: 
function GetDataForOPCServer:Pointer;export;stdcall;
верно это, нет?
PM MAIL   Вверх
Romikgy
Дата 1.11.2006, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

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



Цитата(Unregistered @  1.11.2006,  08:06 Найти цитируемый пост)
структуры TTagName

замени классом 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
bems
Дата 1.11.2006, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



Цитата(Unregistered @  1.11.2006,  09:06 Найти цитируемый пост)
__declspec( dllexport )
     const TDataForOPCServer * PASCAL GetDataForOPCServer( void );

stdcall не нада



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Unregistered
Дата 2.11.2006, 03:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Romikgy @  1.11.2006,  09:40 Найти цитируемый пост)
замени классом  

От этой структуры потом наследуются другие, которые в свою очередь собираются в массив. Я не знаю, каким образом хост-приложение извлекает элементы массива. не вызовет ли это проблем с неправильным распределением памяти? или тут только пробовать? И если я TTagName сделаю классом, то наверное и другие структуры тоже надо? Не понятно что там за pragma надо оно мне нет?
PM MAIL   Вверх
Snowy
Дата 2.11.2006, 03:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

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



Страница по конвертации C в Delphi: http://www.delphi-jedi.org/APICONVTEAMS:686301
PM MAIL   Вверх
Unregistered
Дата 3.11.2006, 03:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ну спасибо конечно. Только вот времени на чтение всего этого у меня нету, и где там как перевести не понятно. Английским владею не настолько хорошо. Скачал конвертер drBob-а - но он мне бредятину какую-то слепил. из TTagName сделал рекорд. Функцию прописал отдельно и тоже с именем TTagName. Также добавил функцию с именем "if". и пр. и др. Самое ценное, что нашел - эквиваленты типов. Но этого не достаточно. Короче - писец, задача не выполнимая. по крайней мере в ближайшие сроки...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

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

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

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


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

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


 




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


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

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