2009-07-29 5 views
1

Я создаю dll C++ Win32 с некоторыми глобальными данными. Существует глобальная карта std :: map, и в DLL есть экспортированные функции, которые записывают данные на карту (после приобретения блокировки записи, конечно).Доступ к глобальным данным в dll из экспортированной DLL-функции

Моя проблема в том, что когда я вызываю функцию записи из DLL DllMain, она работает без проблем. Но когда я загрузить DLL из другой программы и вызвать функцию, которая записывает данные в глобальную карту, он дает мне эту ошибку:

WindowsError: exception: access violation reading 0x00000008 

Есть ли что-то, что можно сделать по этому поводу? Одна и та же функция при вызове из DllMain имеет доступ к глобальным данным в dll, но при вызове из другого процесса он не имеет доступа к глобальным данным. Пожалуйста посоветуй.

Я использую компилятор TDM-MinGW gcc 4.4.0.

EDIT: Хорошо, я понял, что проблема есть, и спасибо за помощь, ребята, но проблема была не с вопросом конструктора или неспособность иметь карты в глобальном пространстве, но вопрос в boost :: python, который я использую. Я тестировал его, но поскольку я вызывал DLL изнутри python или, возможно, что-то, модуль urllib2 не загружался в dll. Теперь я должен посмотреть, как это исправить.

+0

Возможно, это будет хорошая идея, чтобы написать свое решение к этому как ответ и принять его, чтобы вопрос был документирован как «ответ». Либо это, либо принять существующий ответ, который был наиболее полезным. – RBerteig

ответ

1

Похоже, что конструктор std::map еще не запускался при вызове кода. Время жизни глобальных не-POD в DLL Win32 довольно сложно, и я не уверен, как это работает с MinGW. Но может быть, что вы компилируете DLL, вы установили свою собственную функцию (DllMain?) В качестве точки входа и, таким образом, переопределили процедуру инициализации CRT, которая вызывает конструкторы.

+0

Я где-то читал, что все глобальные объекты внутри dll инициализируются до вызова DllMain (DLL_PROCESS_ATTACH). И их деструкторы вызываются после вызова DllMain (DLL_PROCESS_DETACH). Поэтому я предположил, что это сработает и написало слишком много кода, предполагая это. Но если это не работает, было бы безопасно создать глобальный указатель и создать и уничтожить карту внутри DllMain? – Sahas

+0

Я уверен, что конструктор std :: map получает вызов, потому что я вставляю данные в карту в DllMain, когда Dll загружается, но как только он загружается, если я вызываю функцию из другого процесса, он не работает. – Sahas

+0

Что вы подразумеваете под «функцией вызова из другого процесса»? DLL всегда загружается в процесс, в котором он используется. –

0

Вы должны использовать общую память, поскольку разные процессы имеют отдельные адресные пространства. Думаю, вы не получите std :: map running. Я бы рекомендовал использовать MapViewOfFile, CreateFileMapping, OpenFileMapping, ... и простые старые данные. Спросите у Google/MSDN.

+0

Данные, которые я упоминаю, требуется/используется только DLL, которую я создаю, и приложение, использующее DLL, не нуждается в доступе к данным. Есть ли другой способ позволить функции получить доступ к данным? – Sahas

+0

Возможно, вы можете определить один из процессов как владелец данных? И: Являются ли ключи и значения сериализуемыми?Тогда вы могли бы использовать некоторые способы взаимодействия между процессами. Это будет хорошо, если другие процессы не будут слишком сильно использовать карту. –

1

Ошибка чтения на таком низком адресе памяти обычно означает, что вы пытаетесь получить доступ к указателю NULL. Можете ли вы показать свой фактический код?

Смежные вопросы