Thread: DLL`s

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    307

    DLL`s

    OK you will all prob hate me for this "beginner" question...

    i have my program in c++, using the Velleman DLL for accessing the PIC on the relay board

    HOW do i use a dll in C?

  2. #2
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    Assuming the DLL doesn't actually need C++ (e.g. can it throw exceptions?) I don't think it's all that different from doing it from C++.

    So, there are 2 ways you can load DLLs -- you can do it on explicitly during excution, or implicitly at program startup.

    The implicit load at startup way is the simplest, but will only work if the DLL also came with a static library (.lib), and of course a header file. The header file will tell the compiler the definitions it needs, the .lib will keep the linker happy, and the DLL contains the actual code.

    Put the DLL in the same directory as your C executable

    In MSVC project properties, add the path to the header file to 'additional include directories', the .lib name to Additional Library dependencies (under Linker), put the library path in 'additional library paths'.

    You should then be able to call the functions from the DLL just like they were functions declared anywhere else in your project.

    If you've managed to end up without a header or .lib, but you know the innards of the DLL or have good documentation, you can explicitly load the DLL.

    There's some info about the 2 options here: Linking Implicitly

    Do you happen to know what compiler the DLL was built with? There are compatibility issues with VC7 and later MSVCs for some DLLs -- it depends on the characteristics of the DLL. If it's a simple C DLL it should be fine.

  3. #3
    Registered User
    Join Date
    Dec 2012
    Posts
    307
    i only have the dll
    this is what i do with c++

    Code:
    #include <iostream>
    #include <windows.h>
     
    
    using namespace std;
    //----------Set up fuctions from DLL----------//
    typedef void(CALLBACK* t_func)(int );
    typedef void(CALLBACK* t_func0)();
    typedef int(CALLBACK* t_func1)();
    typedef void(CALLBACK* t_func2)(int *, int *);
    typedef void(CALLBACK* t_func3)(int , int );
    typedef int(CALLBACK* t_func4)(int );
    typedef bool(CALLBACK* t_func5)(int );
    t_func4 OpenDevice;
    t_func0 CloseDevice;
    t_func0 Version_;
    t_func4 ReadAnalogChannel;
    t_func2 ReadAllAnalog;
    t_func3 OutputAnalogChannel;
    t_func3 OutputAllAnalog;
    t_func ClearAnalogChannel; 
    t_func0 ClearAllAnalog;
    t_func SetAnalogChannel; 
    t_func0 SetAllAnalog;
    t_func WriteAllDigital;
    t_func ClearDigitalChannel;
    t_func0 ClearAllDigital;
    t_func SetDigitalChannel;
    t_func0 SetAllDigital;
    t_func5 ReadDigitalChannel;
    t_func1 ReadAllDigital;
    //----------Set up functions for control----------//
    int init();
    HINSTANCE hDLL;
    int foundDLL = 0;
    
    int main()
    {
     
     
     int h = init();   
        
     if (!h)
     {
      foundDLL = 1;
     }
     if (foundDLL)
      {
       cout <<"Program Support Files Found"<<endl;
      }
     else
      {
       cout <<"Program Support Files NOT Found"<<endl;
      }
     if (foundDLL == 1)
      {
       OpenDevice(0);
      }
     system("pause");
     if (foundDLL)
      {
       CloseDevice(); 
      }
     FreeLibrary(hDLL);
     return 0;
    }
    int init()
    {
     hDLL = LoadLibrary((LPCWSTR)L"k8055d");
     if (hDLL != NULL)
     {
      OpenDevice = (t_func4) GetProcAddress(hDLL, "OpenDevice");
      if (!OpenDevice)  
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      CloseDevice = (t_func0) GetProcAddress(hDLL, "CloseDevice");
      if (!CloseDevice)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ReadAnalogChannel = (t_func4) GetProcAddress(hDLL, "ReadAnalogChannel");
      if (!ReadAnalogChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ReadAllAnalog = (t_func2) GetProcAddress(hDLL, "ReadAllAnalog");
      if (!ReadAllAnalog)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      OutputAnalogChannel = (t_func3) GetProcAddress(hDLL, "OutputAnalogChannel");
      if (!OutputAnalogChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      OutputAllAnalog = (t_func3) GetProcAddress(hDLL, "OutputAllAnalog");
      if (!OutputAllAnalog)  
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ClearAnalogChannel = (t_func) GetProcAddress(hDLL, "ClearAnalogChannel");
      if (!ClearAnalogChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ClearAllAnalog = (t_func0) GetProcAddress(hDLL, "ClearAllAnalog");
      if (!ClearAllAnalog)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      SetAnalogChannel = (t_func) GetProcAddress(hDLL, "SetAnalogChannel");
      if (!SetAnalogChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      SetAllAnalog = (t_func0) GetProcAddress(hDLL, "SetAllAnalog");
      if (!SetAllAnalog)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      WriteAllDigital = (t_func) GetProcAddress(hDLL, "WriteAllDigital");
      if (!WriteAllDigital)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ClearDigitalChannel = (t_func) GetProcAddress(hDLL, "ClearDigitalChannel");
      if (!ClearDigitalChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ClearAllDigital = (t_func0) GetProcAddress(hDLL, "ClearAllDigital");
      if (!ClearAllDigital)  
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      SetDigitalChannel = (t_func) GetProcAddress(hDLL, "SetDigitalChannel");
      if (!SetDigitalChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      SetAllDigital = (t_func0) GetProcAddress(hDLL, "SetAllDigital");
      if (!SetAllDigital)  
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ReadDigitalChannel = (t_func5) GetProcAddress(hDLL, "ReadDigitalChannel");
      if (!ReadDigitalChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ReadAllDigital = (t_func1) GetProcAddress(hDLL, "ReadAllDigital");
      if (!ReadAllDigital)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      Version_ = (t_func0) GetProcAddress(hDLL, "Version");
      if (!Version_)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      return 0;    // ok
     }       
     return -1;     // error load DLL
    }
    and this dont work in C

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    Ah - ok. Yes, this is what I think you need to do in C, too.

    It doesn't look too bad: no overloaded functions or anything like that. If you remove the iostream include, namespace use, and turn the couts into printfs that'll take care of most of it.

    One of the function prototypes returns a bool. According to Fundamental Types (C++), bool is 1 byte in all recent versions of MSVC - so you should be able to use a 'char' here safely for now (portability hazard but in a file full of Windows DLL handling functions - think the portability gods can look the other way)

  5. #5
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    Yeah, pretty much identical code, just run it through a C compiler and fix the errors/warnings that are generated for all the C++-isms.

    What "doesn't work" about it? Doesn't compile? Doesn't link? Doesn't open the DLL on execution? Doesn't find the named functions inside the DLL (there's possibly something called name-mangling interfering but I'd think it's very unlikely for this example with a manufacturer-supplied DLL)?

    Each of those is a different problem.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  6. #6
    Registered User
    Join Date
    Dec 2012
    Posts
    307
    compiling prob creating dlltest.obj

    Code:
    int init(void)
    {
     hDLL = LoadLibrary((LPCWSTR)L"k8055d");
     if (hDLL != NULL)
     {



    dlltest.c(77): error #2140: Type error in argument 1 to 'function'; expected 'const char *' but found 'const wchar_t *'.

    error was on the following line
    Code:
    hDLL = LoadLibrary((LPCWSTR)L"k8055d");

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    That means that you need to change your project settings from multi-byte to Unicode.
    The code you have above is fine for both C and C++.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  8. #8
    Registered User
    Join Date
    Dec 2012
    Posts
    307
    changed

    Code:
    hDLL = LoadLibrary((LPCWSTR)L"k8055d.dll");
    to

    Code:
    hDLL = LoadLibrary((LPCSTR)L"k8055d.dll");

    and got

    POLINK: error: Unresolved external symbol '_WinMain@16'.
    POLINK: fatal error: 1 unresolved external(s).
    Last edited by Crossfire; 12-30-2012 at 09:46 PM.

  9. #9
    Registered User
    Join Date
    Dec 2012
    Posts
    307
    ok using

    Code:
     
     
    #include<stdio.h>
    #include<windows.h>
     
    
    //----------Set up fuctions from DLL----------//
    typedef void(CALLBACK* t_func)(int );
    typedef void(CALLBACK* t_func0)();
    typedef int(CALLBACK* t_func1)();
    typedef void(CALLBACK* t_func2)(int *, int *);
    typedef void(CALLBACK* t_func3)(int , int );
    typedef int(CALLBACK* t_func4)(int );
    typedef char(CALLBACK* t_func5)(int );
    t_func4 OpenDevice;
    t_func0 CloseDevice;
    t_func0 Version_;
    t_func4 ReadAnalogChannel;
    t_func2 ReadAllAnalog;
    t_func3 OutputAnalogChannel;
    t_func3 OutputAllAnalog;
    t_func ClearAnalogChannel; 
    t_func0 ClearAllAnalog;
    t_func SetAnalogChannel; 
    t_func0 SetAllAnalog;
    t_func WriteAllDigital;
    t_func ClearDigitalChannel;
    t_func0 ClearAllDigital;
    t_func SetDigitalChannel;
    t_func0 SetAllDigital;
    t_func5 ReadDigitalChannel;
    t_func1 ReadAllDigital;
    //----------Set up functions for control----------//
    int init(void);
    HINSTANCE hDLL;
    int foundDLL = 0;
    
    int main(void)
    {
     
     
     int h = init();   
        
     if (!h)
     {
      foundDLL = 1;
     }
     if (foundDLL)
      {
       printf("Program Support Files Found\n");
      }
     else
      {
       printf("Program Support Files NOT Found\n");
      }
     if (foundDLL == 1)
      {
       OpenDevice(0);
      }
     system("pause");
     if (foundDLL)
      {
       CloseDevice(); 
      }
     FreeLibrary(hDLL);
     return 0;
    }
    int init(void)
    {
     hDLL = LoadLibrary((LPCSTR)L"k8055d.dll");
     if (hDLL != NULL)
     {
      OpenDevice = (t_func4) GetProcAddress(hDLL, "OpenDevice");
      if (!OpenDevice)  
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      CloseDevice = (t_func0) GetProcAddress(hDLL, "CloseDevice");
      if (!CloseDevice)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ReadAnalogChannel = (t_func4) GetProcAddress(hDLL, "ReadAnalogChannel");
      if (!ReadAnalogChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ReadAllAnalog = (t_func2) GetProcAddress(hDLL, "ReadAllAnalog");
      if (!ReadAllAnalog)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      OutputAnalogChannel = (t_func3) GetProcAddress(hDLL, "OutputAnalogChannel");
      if (!OutputAnalogChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      OutputAllAnalog = (t_func3) GetProcAddress(hDLL, "OutputAllAnalog");
      if (!OutputAllAnalog)  
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ClearAnalogChannel = (t_func) GetProcAddress(hDLL, "ClearAnalogChannel");
      if (!ClearAnalogChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ClearAllAnalog = (t_func0) GetProcAddress(hDLL, "ClearAllAnalog");
      if (!ClearAllAnalog)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      SetAnalogChannel = (t_func) GetProcAddress(hDLL, "SetAnalogChannel");
      if (!SetAnalogChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      SetAllAnalog = (t_func0) GetProcAddress(hDLL, "SetAllAnalog");
      if (!SetAllAnalog)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      WriteAllDigital = (t_func) GetProcAddress(hDLL, "WriteAllDigital");
      if (!WriteAllDigital)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ClearDigitalChannel = (t_func) GetProcAddress(hDLL, "ClearDigitalChannel");
      if (!ClearDigitalChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ClearAllDigital = (t_func0) GetProcAddress(hDLL, "ClearAllDigital");
      if (!ClearAllDigital)  
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      SetDigitalChannel = (t_func) GetProcAddress(hDLL, "SetDigitalChannel");
      if (!SetDigitalChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      SetAllDigital = (t_func0) GetProcAddress(hDLL, "SetAllDigital");
      if (!SetAllDigital)  
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ReadDigitalChannel = (t_func5) GetProcAddress(hDLL, "ReadDigitalChannel");
      if (!ReadDigitalChannel)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      ReadAllDigital = (t_func1) GetProcAddress(hDLL, "ReadAllDigital");
      if (!ReadAllDigital)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      Version_ = (t_func0) GetProcAddress(hDLL, "Version");
      if (!Version_)
      {      // handle the error
       FreeLibrary(hDLL); 
       return -2;
      }
      return 0;    // ok
     }       
     return -1;     // error load DLL
    }
    now it compiles, but displays

    "Program Support Files NOT Found"

    so does not seem to be loading the dll, that is in the same folder as the project.

    thoughts?

    oh and once in a while when i build the same thing, no errors or warnings, and sometimes i get
    "dlltest.c(47): warning #2203: Function 'main' can't be __stdcall, changed to __cdecl."
    Last edited by Crossfire; 12-31-2012 at 11:41 PM.

  10. #10
    Registered User
    Join Date
    Dec 2012
    Posts
    307
    i have found alot on loading dll`s. Mostly it is from the header and lib files, which i do not have. Evrything else seems to be in C++.

    i am totally lost here, and searching the net, searching my books (the things before ebooks!!) and of course all my ebooks....

    i know someone has to have loaded dll`s in C before....

  11. #11
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    I guessed by doing this with MinGW GCC C Compiler.

    And it appeared to work with the DLL is the same folder as the EXE.

    Code:
    hDLL = LoadLibrary("k8055d.dll");
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  12. #12
    Registered User
    Join Date
    Dec 2012
    Posts
    307
    SON OF A...... out of everything i tried, _T, Text, (LPCSTR),(STR),(LPCWSTR)....The one thing i didnt try, and it worked!!!!

    Stahta, You been great since i joined this board!!! I owe you a couple now, and of course, everyone else too!!!


Popular pages Recent additions subscribe to a feed