Search code examples
c++dllcaplcanoe

Invalid type in dll <dllname.dll><functionname> but I don't see the error


CAPL_DLL_INFO4 table[] = {
{CDLL_VERSION_NAME, (CAPL_FARCALL)CDLL_VERSION, "", "", CAPL_DLL_CDECL, 0xabcd, CDLL_EXPORT },

  ... 
  {"dllTEST",(CAPL_FARCALL)GetAttribute,"CAPL_DLL","...",'I', 5, "IIICI", "\001\001\001\100\001",{ "x","x","x","x","x" } },
  ...

{0, 0}
};
CAPLEXPORT CAPL_DLL_INFO4 far * caplDllTable4 = table;

This is my CAPL Export Table in the sourcefile, which is written in c++ and compiles without errors or warnings to a *.dll. The function interface looks like this in my definition and prototype:

int CAPLEXPORT far CAPLPASCAL GetAttribute(int16 a, int16 b, int16 c, char d[], int16 e);

After successfully implementing the *.dll into CANoe, I get the compile error in CANoe:

CAPL node 'ECU 1': Compilation of '..\ecu.can' failed with error(s)
Invalid type in DLL ..\abc.dll, function dllTEST.

Am I missing something obvious? The used types in the function are all finely casted to CAPL conform types, in this pdf on page 15 you can read about the error:

This error is caught while compiling a CAPL program. The function defined in the CAPL Export Table is incorrect. Most of the time it is the parameter settings in the CAPL Export Table.


Solution

  • According to the "Implementing and Integrating CAPL DLLs" manual, your function declaration and the function table should look something like this:

    long CAPLEXPORT far CAPLPASCAL GetAttribute(long a, long b, long c, char d[], long e);
    
    CAPL_DLL_INFO table[] = {
        {CDLL_VERSION_NAME, (CAPL_FARCALL)CDLL_VERSION, CAPL_DLL_CDECL, 0xabcd, CDLL_EXPORT},
        ... 
        {"dllTEST", (CAPL_FARCALL)GetAttribute, 'L', 5, "LLLCL", "\000\000\000\001\000"},
        ...
        {0, 0}
    };
    
    unsigned long CAPLEXPORT __cdecl caplDllGetTable(void)
    {
        return (unsigned long)table;
    }
    

    Explanation

    1. Since only the 4-th parameter (d) is an array (1-dimensional), the Array Depth Definition is:

      "\000\000\000\001\000"
      
    2. Do not use int16. Use the types described in Table 3 (Function Parameter And Return Value Data Types). Since int and char can only be used if array size !=0, we are using long.