Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
alexdrew
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 2
#1

Эксепшен при загрузке dll, написанной на С - C#

24.03.2012, 20:47. Просмотров 1320. Ответов 2
Метки нет (Все метки)

Здравствуйте.
Разбираюсь с мехинизмом загрузки dll, написанной на С, C# приложением.
Нашел простенький пример и слегка его изменил:

Сама DLL:

C++
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
#include <iostream>
#include <windows.h>
 
using namespace std;
 
void initialize() throw()
{
        // Инициализация после подключения DLL к процессу.
        cout << "DLL: loaded." << endl;
}
 
// API DLL - экспортируемые функции ///////////////////////////////////////////
 
extern "C" void __declspec(dllexport) Test(int i)
{
        cout << "DLL: called 'Test'" << i << endl;
}
 
///////////////////////////////////////////////////////////////////////////////
 
void finalize() throw()
{
        // Завершающие действия перед отключением DLL от процесса.
        cout << "DLL: is free." << endl;
}
 
BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpReserved) throw()
{
        switch(dwReason)
        {
        case DLL_PROCESS_ATTACH:
                initialize();
                break;
        case DLL_PROCESS_DETACH:
                finalize();
                break;
        }
        return TRUE;
}
Приложение:
C#
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
using System;
using System.Runtime.InteropServices;
 
namespace App
{
    class Program
    {
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern IntPtr LoadLibrary(string lpFileName);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern bool FreeLibrary(IntPtr hModule);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern uint GetLastError();
 
 
        delegate void TestDelegate(int i);
 
 
        static void Main(string[] args)
        {
            Console.WriteLine("Application: begin.");
            IntPtr hModule = LoadLibrary("dll.dll");
            if (hModule == IntPtr.Zero)
            {
                Console.WriteLine("Application: Can't load DLL. Error # {0}.", GetLastError());
            }
            else
            {
                IntPtr ptrTest = GetProcAddress(hModule, "Test");
                if (ptrTest == IntPtr.Zero)
                {
                    Console.WriteLine("Application: Function 'Test' not found in DLL.");
                }
                else
                {
                    TestDelegate Test = Marshal.GetDelegateForFunctionPointer(ptrTest, typeof(TestDelegate)) as TestDelegate;
 
                    /// Работа с DLL //////////////////////////////////////////
 
                    Test(7);
 
                    ///////////////////////////////////////////////////////////
                }
                FreeLibrary(hModule);
            }
            Console.WriteLine("Application: end.");
            Console.ReadKey();
        }
    }
}

В результате возникает эксепшен:
PInvokeStackImbalance was detected
A call to PInvoke function 'ConsoleApplication1!ConsoleApplication1.Program+TestDelegate1::Invoke' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

Можно конечно сделать так:
C#
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
using System;
using System.Runtime.InteropServices;
 
namespace App
{
    class Program
    {
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern IntPtr LoadLibrary(string lpFileName);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern bool FreeLibrary(IntPtr hModule);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern uint GetLastError();
 
        [DllImport("new22.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        static extern void Test(int i);
 
        static void Main(string[] args)
        {
            Console.WriteLine("Application: begin.");
            Test(7);
            Console.WriteLine("Application: end.");
            Console.ReadKey();
        }
    }
}
Тогда эксепшен не возникает. Но в этом случае отсутствует проверка на загрузку dll. Что не очень хорошо.
Подскажите, пожалуйста, как можно добавить проверку на загрузку dll во втором случае, или исправить возникновение эксепшена в первом?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.03.2012, 20:47
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Эксепшен при загрузке dll, написанной на С (C#):

Запуск dll при загрузке Windows - C#
Подскажите я много слышал о том что запускается винда все дела но потом еще и запускается моя программа только она не в ехе а длл....

Внедрение Dll, написанной на C++ в Exe - C#
Внедрение Dll в Exe (Не взлом! Свою Длл в свою Ехе)... Я создаю в с++ определённую Dll-ky, там есть как бы меню.. Это меню мне нужно...

C# импорт метода из Dll написанной на C++ - C#
Всем привет! Вот какая проблема. Нужно вызвать метод из Dll написанный на c++. Вот как выглядит его прототип: USTEXPORT USTFUNC...

Импорт функции из DLL написанной на С++ - C#
Есть dll файл написанный на С++ (Visual Studio) Работал с этой библиотекой в Autoit (скриптовый язык). Сейчас хочу сделать вызов из...

Использование DLL, написанной на delphi - C#
Есть DLL CscLink.dll, но описание к ней на delphi Так как в delphi &quot;0&quot;, пытаюсь использовать в C#. Ряд функци уже реализовал из...

Подключение к проекту DLL, написанной на Си - C#
Требуется добраться до функций реализованных в dll, написанной на сишке. using System.Runtime.InteropServices; Далее в...

2
m0nax
1199 / 904 / 62
Регистрация: 12.01.2010
Сообщений: 1,889
Завершенные тесты: 3
24.03.2012, 20:52 #2
вот это все
C#
1
2
3
4
5
6
7
8
9
10
11
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern IntPtr LoadLibrary(string lpFileName);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern bool FreeLibrary(IntPtr hModule);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
 
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)]
        static extern uint GetLastError();
и весь код который это использует - не нужно

достаточно просто
C#
1
2
 [DllImport("new22.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        static extern void Test(int i);
и вызвать ее потом просто Test();
0
alexdrew
0 / 0 / 0
Регистрация: 21.03.2012
Сообщений: 2
24.03.2012, 22:34 #3
Спасибо за поправку.
Но в этом случае также не будет проверки на загрузку dll.
Меня это и останавливает в этом подходе.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.03.2012, 22:34
Привет! Вот еще темы с ответами:

Использование функций DLL, написанной на C++ - C#
В проекте C# нужно использовать функции, написанные на с++. Создал DLL-ку, все отлично цепляется. Вопрос в том, что в с++ проекте есть своя...

Работа с DLL, написанной на Delphi - C#
Доброго всем времени суток. В C# мягко говоря новичок и, честно признаться, немного не в курсе, реально это вообще или нет. Есть...

Использование DLL, написанной на C++, в C# (указатели) - C#
Всем привет! Есть DLL, написанная на C++, в ней описана такая функция: int ReadData(int kpn,int bn,OUT DWORD*time,OUT...

Подключение dll, написанной на C++ к проекту - C#
Здравствуйте, уважаемые форумчане! Столкнулся с такой проблемой: не могу подключить написанную на C++ dll-ку к проекту на шарпе. Описание...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru