Entwickler-Ecke

C# - Die Sprache - Fehler bein DLL Include


mbuettner - Mo 08.03.10 14:29
Titel: Fehler bein DLL Include
Hallo,

die Fehlermeldung im Anhang bekomme ich, wenn ich auf eine DLL zugreifen will. Ich habe in der DLL auch schon versucht ..(string path) zu verwenden, aber dann spuckt der Compiler nur Fehlermeldungen aus. Wie kann ich es machen, dass die Fehlermeldung nicht auftaucht?


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Scanner{
  public class SteuerelementeForm : System.Windows.Forms.Form 
  {
    [DllImport("dialog_dll.dll")]
    public static extern void opendialog(char path);
    private Button load;
    
    public SteuerelementeForm(){
      Name = "ScannerForm";
      Text = "ice-Basic Scanner";
      Font = new Font("Courier New"10F, (FontStyle.Bold), GraphicsUnit.Point, ((System.Byte)(0)));
      FormBorderStyle = FormBorderStyle.FixedDialog;
      Location = new Point(0,0);
      Size = new Size(500,400);
      Komponenten();
    }
    private void Komponenten(){
      load = new Button();
      
      load.Location = new Point(400,8);
      load.Size = new Size(80,20);
      load.Text = "Laden...";
      load.Click += new EventHandler(opendialog);
      
      Controls.Add(load);
    } 
    private void opendialog(object sender, EventArgs e)
    {
      opendialog(Convert.ToChar(Application.StartupPath));
    }  
    public static void Main(){
      try{
        Application.Run(new SteuerelementeForm());
      }catch(Exception ex){
        MessageBox.Show(ex.Message);
      }
    }
  }
}


MfG
Markus


JüTho - Mo 08.03.10 14:56

Fehlermeldung vergessen. Besser nicht per Anhang, sondern per Zitat; dazu kann bei einer MessageBox oft auch Strg-C verwendet werden. Jürgen


danielf - Mo 08.03.10 15:54

Hallo,

kannst du uns noch die Dekleration in der C-API geben?

Danke & Gruß
Daniel


Th69 - Mo 08.03.10 19:55

Hallo mbuettner,

ein Char ist nur genau ein Zeichen groß, da paßt kein ganzer Pfad rein.

Mit "string path" war es sicherlich schon richtig (solange in der C-API "const char *" dafür verwendet wurde).
Du mußt dann nur beim Aufruf das "Convert.ToChar" weglassen (welches die Fehlermeldung verursacht hat!).


mbuettner - Mo 08.03.10 21:22

Hallo,

der Code für die DLL:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
//main.cpp
#include "main.h"

BOOL LoadText(LPCTSTR pszFileName)
{
   HANDLE hFile;
   BOOL bSuccess = FALSE;

   hFile = CreateFile(pszFileName, GENERIC_READ,
                       FILE_SHARE_READ, NULL,
                       OPEN_EXISTING, 0, NULL);
   if(hFile != INVALID_HANDLE_VALUE)
      {
         DWORD dwFileSize;

         dwFileSize = GetFileSize(hFile, NULL);
         if(dwFileSize != 0xFFFFFFFF)
         {
            LPSTR pszFileText;

           pszFileText=(char *)GlobalAlloc(GPTR, dwFileSize + 1);
            if(pszFileText != NULL)
            {
               DWORD dwRead;
               if(ReadFile( hFile, pszFileText, dwFileSize,
                             &dwRead, NULL )   )
                  {
                     pszFileText[dwFileSize] = '\0';
                  }
               GlobalFree(pszFileText);
            }
         }
         CloseHandle(hFile);
      }
   return bSuccess;
}
void DLL_EXPORT opendialog(const char * path)
{
    OPENFILENAME ofn;
    char szFileName[MAX_PATH] = "";

    ZeroMemory(&ofn, sizeof(ofn));

    ofn.lStructSize = sizeof(ofn);
    ofn.lpstrFilter = "iceBasic (*.ib)\0*.ib\0";
    ofn.lpstrFile = szFileName;
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST |
                OFN_HIDEREADONLY;
    ofn.lpstrDefExt = "IceBasic";

    if(GetOpenFileName(&ofn))
       {
          if(LoadText(szFileName))
             {
                 MessageBox( NULL, "Laden erfolgreich",
                      "IceBasic",MB_ICONEXCLAMATION | MB_OK  );
             }
       }
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            break;

        case DLL_PROCESS_DETACH:
            // detach from process
            break;

        case DLL_THREAD_ATTACH:
            // attach to thread
            break;

        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
//main.h
#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>
#include <string.h>

/*  To use this exported function of dll, include this header
 *  in your project.
 */

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif


#ifdef __cplusplus
extern "C"
{
#endif

void DLL_EXPORT opendialog(char path);

#ifdef __cplusplus
}
#endif

#endif // __MAIN_H__

Wenn ich string path verwenden will, spuckt der Compiler folgendes aus:
Zitat:
E:\CodeBlocks\dialogs_dll\main.cpp:36: error: variable or field `opendialog' declared void
E:\CodeBlocks\dialogs_dll\main.cpp:36: error: `int opendialog' redeclared as different kind of symbol
E:\CodeBlocks\dialogs_dll\main.h:23: error: previous declaration of `void opendialog(char)'
E:\CodeBlocks\dialogs_dll\main.cpp:36: error: declaration of `int opendialog'
E:\CodeBlocks\dialogs_dll\main.h:23: error: conflicts with previous declaration `void opendialog(char)'
E:\CodeBlocks\dialogs_dll\main.cpp:36: error: `string' was not declared in this scope
E:\CodeBlocks\dialogs_dll\main.cpp:37: error: expected `,' or `;' before '{' token


danielf - Mo 08.03.10 21:31

Du sollst das nicht in der Header Datei ändern, sonder in dem .NET-Teil bei

C#-Quelltext
1:
2:
[DllImport("dialog_dll.dll")]
public static extern void opendialog(char path);


mbuettner - Di 09.03.10 11:07

Ja, aber dann muss ich in der DLL trotzdem string path angeben, sonst meckert der Compiler wieder.


danielf - Di 09.03.10 11:31

main.cpp:

Quelltext
1:
2:
3:
4:
void DLL_EXPORT opendialog(const char * path)
{
 ....
}


main.h

Quelltext
1:
void DLL_EXPORT opendialog(const char * path);                    


im .net projekt

C#-Quelltext
1:
2:
[DllImport("dialog_dll.dll")]
public static extern void opendialog(string path);


mbuettner - Di 09.03.10 14:55

Jetzt hängt der sich, sobald ich den Öffnen Dialog will, auf.


danielf - Di 09.03.10 16:19

Warum hast du dir den so eine Architektur ausgedacht? Den Sinn verstehe ich überhaupt nicht.

Okay.. TreiberDLL in c++... aber einen Dialog?

Was willst du im c++ Teil und was im .NET-Teil machen? SChonmal darüber nachgedacht?


mbuettner - Mi 10.03.10 17:57

Ich habe des ganze mit ins C# Programm gemacht, aber Jetzt kommt dann immer:
cs3
Ich kann für
string[] args = new String[x]; Alles für x einsetzen, Resultat immer das gleiche.
Warum passiert der Fehler überhaupt?


Ralf Jansen - Mi 10.03.10 19:18

Weil du im Code auf einen Index im Array größer x-1 zugreifst. Z.B. args[x]