Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> C++ и Delphi DLL: проблема с потоками, Проблема с потоками 
:(
    Опции темы
hvzh
Дата 12.4.2011, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Доброе время суток!
У меня возникла проблема с вызовом функции из паскалевой DLL. Суть проблемы: имеется прога, написанная на VC++ и Delphi DLL, функции которой юзает сишная прога. В одной из паскалевых функций создается поток. Как только сишная прога вызывает эту функцию, происходит отвал. Вот пример тестовой проги:

Код

#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <Windows.h>

typedef bool(__stdcall *SealControllerType)(int);
typedef bool(__stdcall *SealControllerType1)();

int _tmain(int argc, _TCHAR* argv[])
{
    int par = 4;
    SetDllDirectory(TEXT("g:\\"));
    HMODULE hdll = ::LoadLibrary(TEXT("SealController.dll"));
    if(hdll)
    {
        printf("Dll is loaded\n");
        SealControllerType f = (SealControllerType)::GetProcAddress(hdll, "InitController");
        printf("Assa1\n");
        if(!f)
            printf("Can not find function InitController\n");
        else
        {
            printf("Before calling function InitController\n");
            bool s = f(1);  // ВОТ ЗДЕСЬ ОТВАЛИВАЕТСЯ (ВЕРНЕЕ, КОД ИСПОЛНЯЕТСЯ ДО КОНЦА, НО ПРИ СОЗДАНИИ ПОТОКА В ЭТОЙ ФУНКЦИИ ПРОИСХОДИТ ОТВАЛ)
            printf( "InitController: %d\n", s );
        }

        SealControllerType1 g = (SealControllerType1)::GetProcAddress(hdll, "GetControllerStatus");
        if(!f)
            printf("Can not find function GetControllerStatus\n");
        else
        {
            printf("Before calling function GetControllerStatus\n");
            bool s = g();
            printf( "GetControllerStatus: %d\n", s );
        }
        ::FreeLibrary(hdll);
    }
    else 
        printf("DLL not found... Is it exists? Error = %d\n", GetLastError());
    system("PAUSE");
    return 0;
}


Есть ли у кого идеи по поводу того, в чем может быть проблема. Любую дополнительную инфу за исключением паскалевых исходников могу предоставить.

PM MAIL   Вверх
Dem_max
Дата 12.4.2011, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

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



что значит происходит отвал ???


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
hvzh
Дата 12.4.2011, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Dem_max @ 12.4.2011,  10:59)
что значит происходит отвал ???

Unhandled exception at 0x002a45f1 in SafeTest.exe: 0xC0000005: Access violation writing location 0x00000004.
PM MAIL   Вверх
Dem_max
Дата 12.4.2011, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

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



приведи код паскаля этой функции и объявление этой функции для экспорта 


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
hvzh
Дата 12.4.2011, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Dem_max @ 12.4.2011,  11:04)
приведи код паскаля этой функции и объявление этой функции для экспорта

Существует функция со следующим объявлением:
Код

function InitController(AComNum: Integer): boolean; cdecl;


Последним шагом в ней - создание потока с использованием следующих функций:


Код

unit ZThread;

interface

uses
   SysUtils, Classes, DateUtils;

type
   TCheckStatusThread = class(TThread)
   public
      gLastCheckStatusTime,
      gLastWatchdogPingTime : TDateTime;
      gOldStatusByte1,
      gOldStatusByte2,
      gOldStatusByte3,
      gOldStatusByte4 : Byte;
      procedure Execute; override;
   end;

var
   gCheckStatusThread: TThread = nil;

procedure StartCheckStatusThread;
procedure StopCheckStatusThread;


implementation

uses
  ZapaykaController, FillyUtils;

procedure StartCheckStatusThread;
begin
   if gCheckStatusThread <> nil then
      Exit;
   gCheckStatusThread := TCheckStatusThread.Create(False);
end;


procedure StopCheckStatusThread;
begin
   gCheckStatusThread.Terminate;
end;

{ TCheckStatusThread }

procedure TCheckStatusThread.Execute;
var   b1, b2, i, j: Byte;
begin
  inherited;
  gLastCheckStatusTime := Now;
  while not Terminated do begin
    try
    continue;

    except
    end;
    Sleep(1);
  end;
end;

end.


Этот поток в данный момент ничего не выполняет, но ошибка при его создании тем не менее возникает

PM MAIL   Вверх
Dem_max
Дата 12.4.2011, 11:31 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

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



у тебя паскалевская функция экспортируется как __cdecl, а ты в сишной проге пытаешься ее импортировать как __stdcall, вот и получаешь свой эксепшн.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
hvzh
Дата 12.4.2011, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Dem_max @ 12.4.2011,  11:31)
у тебя паскалевская функция экспортируется как __cdecl, а ты в сишной проге пытаешься ее импортировать как __stdcall, вот и получаешь свой эксепшн.

Сорри, это рудимент, поскольку пробовались и __cdecl и __stdcall. На данный момент и там, и там __stdcall
PM MAIL   Вверх
Dem_max
Дата 12.4.2011, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

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



тогда я не вижу паскалевского кода с функцией InitController


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
GremlinProg
Дата 12.4.2011, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



в принципе, можно отладить паскалевскую библиотеку и посмотреть, что там не так,
а вот по коду придерусь только пожалуй к этому:
Цитата(hvzh @  12.4.2011,  13:27 Найти цитируемый пост)

procedure TCheckStatusThread.Execute;
var   b1, b2, i, j: Byte;
begin
  inherited;
  gLastCheckStatusTime := Now;
  while not Terminated do begin
    try
    continue;
    except
    end;
    Sleep(1);
  end;
end;

разве унаследованный TThread.Execute не поднимает исключение, может все же убрать эту строку?


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
hvzh
Дата 12.4.2011, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Dem_max @ 12.4.2011,  11:47)
тогда я не вижу паскалевского кода с функцией InitController

Вот полный кусок кода:
Код

 function InitController(AComNum: Integer): boolean; stdcall; export;
begin
  Result := False;
  gController.COMPortNum := AComNum;
  gController.SaveFluidLog := False;
  gController.SaveCMDLog := False;
  Result := gController.OpenCOMPort;
end;

function TcntrZapayka.OpenCOMPort: boolean;
begin
   Result := False;
   try
      CloseCOMPort;
      if not InitCOMPort(FCOMPortNum, cS_COM9600) then
         Exit;
      StartCheckStatusThread;
   except
      on e: Exception do
         raise EZapaykaController.Create('InitCOMPort function error: ' + e.Message);
   end;
   Result := True;
end;


Слетает при вызове StartCheckStatusThread в функции OpenCOMPort

PM MAIL   Вверх
Dem_max
Дата 12.4.2011, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

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



Это жесткий код тоже, грохать поток вместо того чтобы корректно его завершить.
Код

procedure StopCheckStatusThread;
begin
   gCheckStatusThread.Terminate;
end;



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
hvzh
Дата 12.4.2011, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код паскалевый писал не я, доступа ко всему коду нет, так что отладиться не могу
PM MAIL   Вверх
Dem_max
Дата 12.4.2011, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

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



Тогда бессмыслено искать ошибки в закрытом коде


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
hvzh
Дата 12.4.2011, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



GremlinProg
inherited убрал он, все равно Access violation
PM MAIL   Вверх
Alca
Дата 12.4.2011, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Цитата

Это жесткий код тоже, грохать поток вместо того чтобы корректно его завершить.код Pascal/Delphi
Цитата

procedure StopCheckStatusThread;
begin
   gCheckStatusThread.Terminate;
end;


VCL-вский метод класса TThread как раз это и делает, т.е. ставить флаг завершения работы потока (это не апишная функция ::TerminateThread).
Название подобрано неудачно


--------------------
PM WWW ICQ Skype Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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