Matheus Miguel Postado Maio 26, 2020 em 18:47 Compartilhar Postado Maio 26, 2020 em 18:47 E ai Pessoal! Beleza? Estou trabalhando com simulações no Ansys (AQWA) e estou tendo problemas para compilar uma DLL que exportará funções para a simulação. Estou usando o Visual Studio 2019, com um tamplate Biblioteca de Vínculo Dinâmico (DLL). Sou bem iniciante com este tipo de programação, pelo desculpas caso o erro seja muito tolo Esses são os meus algortimos: //user_force64.cpp #include "user_force.h" #include "pch.h" #include <stdio.h> extern "C" { __declspec(dllexport) void _stdcall USER_FORCE(int* Mode, int I_Control[100], float R_Control[100], int* Nstruc, float* Time, float* TimeStep, int* Stage, float Position[][6], float Velocity[][6], float Cog[][3], float Force[][6], float Addmass[][6][6], int* ErrorFlag) { // // *** Visual C++ Template // ----------------------- // // 1. Uses stdcall calling convention // 2. Routine name MUST be in upper case // 3. All parameters are passed as pointers // // Input Parameter Description: // // Mode int* - 0 = Initialisation. This routine is called once with mode 0 // before the simulation. All parameters are as described // below except for STAGE, which is undefined. FORCES and // ADDMAS are assumed undefined on exit. // IERR if set to > 0 on exit will cause // the simulation to stop. // // 1 = Called during the simulation. FORCE/ADDMAS output expected. // // 99 = Termination. This routine is called once with mode 99 // at the end of the simulation. // // I_Control[100] - User-defined integer control parameters input in .DAT file. // (int*) // // R_Control[100] - User-defined real control parameters input in .DAT file. // (float*) // // Nstruc int* - Number of structures in the the simulation // // Time float* - The current time (see Stage below) // // Timestep float* - The current timestep (DT, see Stage below) // // Stage int* - The stage of the integration scheme. AQWA time integration is // based on a 2-stage predictor corrector method. This routine is // therefore called twice at each timestep, once with STAGE=1 and // once with STAGE=2. On stage 2 the position and velocity are // predictions of the position and velocity at TIME+DT. // e.g. if the initial time is 0.0 and the step 1.0 seconds then // calls are as follows for the 1st 3 integration steps: // // CALL USER_FORCE(.....,TIME=0.0,TIMESTEP=1.0,STAGE=1 ...) // CALL USER_FORCE(.....,TIME=0.0,TIMESTEP=1.0,STAGE=2 ...) // CALL USER_FORCE(.....,TIME=1.0,TIMESTEP=1.0,STAGE=1 ...) // CALL USER_FORCE(.....,TIME=1.0,TIMESTEP=1.0,STAGE=2 ...) // CALL USER_FORCE(.....,TIME=2.0,TIMESTEP=1.0,STAGE=1 ...) // CALL USER_FORCE(.....,TIME=2.0,TIMESTEP=1.0,STAGE=2 ...) // // Cog[Nstruc][3] - Position of the Centre of Gravity in the Definition axes. // // Position[Nstruc][6] - Position of the structure in the FRA - angles in radians // (float*) // // Velocity[Nstruc][6] - Velocity of the structure in the FRA // (float*) angular velocity in rad/s // // // Output Parameter Description: // // Force[Nstruc][6] - Force on the Centre of gravity of the structure. NB: these // (float) forces are applied in the Fixed Reference axis e.g. // the surge(X) force is ALWAYS IN THE SAME DIRECTION i.e. in // the direction of the X fixed reference axis. // // Addmass[Nstruc][6][6] // (float) - Added mass matrix for each structure. As the value of the // acceleration is dependent on FORCES, this matrix may be used // to apply inertia type forces to the structure. This mass // will be added to the total added mass of the structure at each // timestep at each stage. // // Errorflag int* - Error flag. The program will abort at any time if this // error flag is non-zero. The values of the error flag will // be output in the abort message. int i, j; int struc = 1; //------------------------------------------------------------------------ // MODE#0 - Initialise any summing variables/open/create files. // This mode is executed once before the simulation begins. //------------------------------------------------------------------------ if (*Mode == 0) { } //------------------------------------------------------------------------ // MODE#1 - On-going - calculation of forces/mass //------------------------------------------------------------------------ else if (*Mode == 1) { for (struc = 0; struc < *Nstruc; struc++) { for (i = 0; i < 6; i++) { Force[struc][i] = 2 * Velocity[struc][i]; for (j = 0; j < 6; j++) { Addmass[struc][j][i] = 0.0; } } } *ErrorFlag = 0; } //------------------------------------------------------------------------ // MODE#99 - Termination - Output/print any summaries required/Close Files // This mode is executed once at the end of the simulation //------------------------------------------------------------------------ else if (*Mode == 99) { } //------------------------------------------------------------------------ // MODE# ERROR - OUTPUT ERROR MESSAGE //------------------------------------------------------------------------ else { } return; } } -------------------------------------------------------------------- //user_force.h #pragma once extern "C" { __declspec(dllexport) void _stdcall USER_FORCE(int* Mode, int I_Control[100], float R_Control[100], int* Nstruc, float* Time, float* TimeStep, int* Stage, float Position[][6], float Velocity[][6], float Cog[][3], float Force[][6], float Addmass[][6][6], int* ErrorFlag) } -------------------------------------------------------------------------- // dllmain.cpp : Define o ponto de entrada para o aplicativo DLL. #include "pch.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; } Depois de usar o comando dumpbin /exports na DLL gerada, esta é a mensagem: Section contains the following exports for user_force64.dll 00000000 characteristics FFFFFFFF time date stamp 0.00 version 1 ordinal base 1 number of functions 1 number of names ordinal hint RVA name 1 0 00011046 _USER_FORCE@52 = @ILT+65(_USER_FORCE@52) Summary 1000 .00cfg 1000 .data 1000 .idata 1000 .msvcjmc 2000 .rdata 1000 .reloc 1000 .rsrc 6000 .text 10000 .textbss E quando uso o mesmo comando em uma DLL funcional, este é o output Dump of file user_force64.dll File Type: DLL Section contains the following exports for user_force64.dll 00000000 characteristics 5D3F15AA time date stamp Mon Jul 29 12:50:02 2019 0.00 version 1 ordinal base 1 number of functions 1 number of names ordinal hint RVA name 1 0 00001000 USER_FORCE Summary 1000 .data 1000 .pdata 1000 .rdata 1000 .reloc 1000 .rsrc 1000 .text Aparentemente errei alguma coisa na compilação, o que causou a diferença no nome da função exportada. Link para o comentário Compartilhar em outros sites More sharing options...
Fernando Mercês Postado Maio 26, 2020 em 22:24 Compartilhar Postado Maio 26, 2020 em 22:24 Citar _USER_FORCE@52 = @ILT+65(_USER_FORCE@52) Interessante... eu nunca tinha visto esse padrão de nome. Não me parece o name decoration / mangling normal de C++. E mesmo assim o extern "C" deveria impedir a decoração, claro, já que C não tem sobrecarga de funções. Será que não há uma função com o mesmo nome nessa pch.h? Achei uma discussão longa de um usuário com um problema muito parecido, inclusive ele cita o mesmo padrão de nomes aqui. Bem, eu iria com baby steps, saca? Compila a menor possível, checa os exports e, se tiver tudo certo, vai crescendo o código e checando os exports da DLL compilada, até encontrar o problema. Por exemplo, o código abaixo foi sem problemas aqui: // user_force.h int _stdcall USER_FORCE(int a, int b); 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; } // user_force.cpp extern "C" __declspec(dllexport) int _stdcall USER_FORCE(int a, int b) { return a + b; } Compilação: c:\Users\admin\Documents>cl /LD user_force.cpp Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64 Copyright (C) Microsoft Corporation. All rights reserved. user_force.cpp Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:user_force.dll /dll /implib:user_force.lib user_force.obj Creating library user_force.lib and object user_force.exp Checagem dos exports: c:\Users\admin\Documents>dumpbin /exports user_force.dll Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file user_force.dll File Type: DLL Section contains the following exports for user_force.dll 00000000 characteristics 5ECD966F time date stamp Tue May 26 23:21:35 2020 0.00 version 1 ordinal base 1 number of functions 1 number of names ordinal hint RVA name 1 0 00001000 USER_FORCE Summary 3000 .data 1000 .pdata 2000 .rdata 1000 .reloc Daí seria ir acrescentando o código e recompilando toda hora, até achar o problema... Mas pode ser que alguém saiba exatamente o que ocorre aqui e ajude também. Abraço! Link para o comentário Compartilhar em outros sites More sharing options...
Matheus Miguel Postado Maio 28, 2020 em 17:25 Autor Compartilhar Postado Maio 28, 2020 em 17:25 Agradeço sua resposta, Fernando Mercês Fiz exatamente como você fez. Porém a checagem dos exports foi a seguinte: File Type: DLL Section contains the following exports for user_force.dll 00000000 characteristics FFFFFFFF time date stamp 0.00 version 1 ordinal base 1 number of functions 1 number of names ordinal hint RVA name 1 0 00001000 _USER_FORCE@8 Summary 2000 .data 6000 .rdata 1000 .reloc B000 .text C:\Users\l04392\source\repos\teste\teste> Esqueci de comentar quando criei o post que o manual do ANSYS diz: " On Windows, the name of the .DLL file must be user_force64.dll, and the file must be located in the same directory as the Aqwa executables (typically C:\Program Files\ANSYS Inc\v201\aqwa\bin\winx64)" Então creio que basta compilar e colocar nesta pasta, certo? Mesmo assim, dá "Solver aborted". A simulação simplesmente não roda Fernando Mercês Você poderia me enviar seu projeto do VS? Link para o comentário Compartilhar em outros sites More sharing options...
Fernando Mercês Postado Maio 28, 2020 em 22:28 Compartilhar Postado Maio 28, 2020 em 22:28 Eu nem criei um projeto, @Matheus Miguel. Criei os dois arquivos e compilei com a linha de comando. ? Link para o comentário Compartilhar em outros sites More sharing options...
Posts Recomendados
Arquivado
Este tópico foi arquivado e está fechado para novas respostas.