Создание DLL из существующего (но старого) примера кода - PullRequest
0 голосов
/ 31 мая 2018

У меня проблема с кодом, который создает DLL (или может из-за настроек компилятора).

Я пытаюсь создать DLL, которая работает как расширение программного пакета (ZEMAX), работающего под Windows.64 - хотя программное обеспечение OLD (2005) - его обновление стоило бы> 5000 долларов, и оно работает нормально, поэтому имеет смысл попробовать.

Программное обеспечение (ZEMAX) использует файлы dll для расширения своих возможностей и ожидаетв этих DLL есть функции, которые принимают параметры и возвращают заданные значения.Пример кода приведен, я могу скомпилировать его в DLL, но программное обеспечение просто не может найти функции.

Пример кода предоставлен ZEMAX, в который я внес небольшие изменения.Я хочу создать four_angle.dll.Ключевые строки в примере кода (который все в C #, и я бы не стал переписывать все это):

int __declspec(dllexport) APIENTRY UserParamSourceDefinition(double *data);
int __declspec(dllexport) APIENTRY UserParamNames(char *data);

BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
    return TRUE;
}

и позже

int __declspec(dllexport) APIENTRY UserParamNames(char *data)
{
    strcpy_s(data[1],16,'hello');
}

int __declspec(dllexport) APIENTRY UserSourceDefinition(double *data)
{
    data[30] = (double)data[2] + 1.0;
}

Компиляции Visual Studioбез ошибок.Есть ли причина, по которой эти функции не могут быть вызваны программным обеспечением, которое загружает DLL во время выполнения?Я новичок в создании dll, поэтому я не знаю, как работают эти определения определений и опции для DLLMain.

PS - Я заметил, что Visual Studio также создала DLLmain, который я прокомментировал, поскольку вы не можете определить что-то дважды.Опять же, у меня только много идей о том, как это работает, и если я собираюсь заполнить некоторые из описаний дел.

#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call,LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

PPS Я следовал инструкциям здесь - но безудача: http://customers.zemax.com/os/resources/learn/knowledgebase/how-to-compile-a-user-defined-surface.aspx

1 Ответ

0 голосов
/ 31 мая 2018

Учитывая, что:

  • И WINAPI, и APIENTRY являются просто #define с __stdcall
  • Согласно Зависимость Уокер ,Функция UserParamNames экспортируется .dll версией, которая:
    • Работает: как _UserParamNames@4
    • Не работает: как ?UserParamNames@@YGHPAD@Z

следующие выводы:

  • Код скомпилирован (и функции экспортированы) как C ++ (проверьте [MSDN]:Декорированные имена )
  • Целевая архитектура 32-битная ( Win32 или x86 )

Я только догадываюсь здесь, но большинствоскорее всего, вы поместили определения функций в файл .cpp (который по умолчанию скомпилирован как C ++ ).

Чтобы исправить проблему, экспортируйте свои функции как C .Ваш фрагмент кода 1 st изменен (вам придется делать то же самое для каждой функции, которая имеет эту проблему).Вы можете сделать это, как показано ниже, или добавить extern "C" для каждой функции отдельно.

#if defined(__cplusplus)
extern "C" {
#endif

    __declspec(dllexport) int APIENTRY UserParamSourceDefinition(double *data);
    __declspec(dllexport) int APIENTRY UserParamNames(char *data);

#if defined(__cplusplus)
}
#endif

Для получения более подробной информации (информация, код, ресурсы), проверьте:

...