C Объекты периода выполнения, dll границы

Проблема в том, что вы пытаетесь получить доступ к ресурсам (в данном случае к строкам) с помощью getResources (). GetString (), который попытается получить ресурсы из Activity. Посмотрите этот исходный код класса Fragment:

 /**
  * Return <code>getActivity().getResources()</code>.
  */
 final public Resources getResources() {
     if (mHost == null) {
         throw new IllegalStateException("Fragment " + this + " not attached to Activity");
     }
     return mHost.getContext().getResources();
 }

mHost - это объект, который содержит вашу активность.

Поскольку действие не может быть присоединено, ваш вызов getResources () вызовет исключение.

Принятое решение ИМХО - это не тот путь, которым вы просто скрываете проблему. Правильный способ - просто получить ресурсы из другого места, которое всегда гарантированно существует, например, из контекста приложения:

youApplicationObject.getResources().getString(...)
6
задан David Cournapeau 27 June 2009 в 09:28
поделиться

4 ответа

Вы запросили решение на C, а не на C ++.

Обычные методы для выполнения подобных действий на C:

  • Разработайте API модулей, чтобы просто не требуются объекты CRT. Получите данные, передаваемые в необработанных типах C, т.е. заставьте потребителя загрузить файл и просто передать вам указатель. Или попросите потребителя передать полностью определенное имя файла, которое открывается, читается и закрывается внутри.

  • На ум приходит подход, используемый другими модулями c, MS кабинет SD и частями библиотеки OpenSSL iirc, заставить приложение-потребитель передать указатели на функции функции инициализации. Таким образом, любой API, которому вы передаете FILE *, в какой-то момент во время инициализации принял бы указатель на структуру с указателями функций, соответствующими сигнатурам fread, fopen и т. Д.

2
ответ дан 17 December 2019 в 18:19
поделиться

Ни один из существующих ответов не является правильным: Учитывая следующее в Windows: у вас есть две библиотеки DLL, каждая из которых статически связана с двумя разными версиями стандартных библиотек C / C ++.

В этом случае, вы не должны передавать указатели на структуры, созданные стандартной библиотекой C / C ++ в одной DLL, в другую. Причина в том, что эти структуры могут отличаться в двух реализациях стандартной библиотеки C / C ++.

Еще одна вещь, которую вам не следует делать, - это освобождать указатель, выделенный функцией new или malloc, из одной библиотеки DLL, которая была выделена в другой. Менеджер кучи также может быть реализован по-другому.

Обратите внимание, вы можете использовать указатели между библиотеками DLL - они просто указывают на память. Проблема в бесплатном.

Вы можете обнаружить, что это работает, но если это так, то вам просто повезло. Это может вызвать у вас проблемы в будущем.

Одно из возможных решений вашей проблемы - динамическое соединение с CRT . Например, вы можете динамически ссылаться на MSVCRT.DLL. Таким образом, ваша DLL всегда будет использовать один и тот же CRT.

Обратите внимание: я считаю, что передача структур данных CRT между библиотеками DLL - не лучшая практика. Возможно, вы захотите посмотреть, сможете ли вы лучше разложить ситуацию.

Обратите внимание, я не эксперт по Linux / Unix - но у вас будут те же проблемы и в этих ОС.

Возможно, вы захотите посмотреть, сможете ли вы лучше разложить ситуацию.

Обратите внимание, я не эксперт по Linux / Unix - но у вас будут те же проблемы и в этих ОС.

Возможно, вы захотите посмотреть, сможете ли вы лучше разложить ситуацию.

Обратите внимание, я не эксперт по Linux / Unix - но у вас будут те же проблемы и в этих ОС.

1
ответ дан 17 December 2019 в 18:19
поделиться

The problem with the different runtimes isn't solvable because the FILE* struct belongs к одной среде выполнения в системе Windows.

Но если вы напишете небольшую оболочку Interface, то все готово, и это на самом деле не повредит.

stdcall IFile* IFileFactory(const char* filename, const char* mode);

class IFile {

  virtual fwrite(...) = 0;
  virtual fread(...) = 0;

  virtual delete() = 0; 
}

Это сохранение, которое повсюду передается через границы DLL, и на самом деле это не повредит.

PS: Будьте осторожны, если вы начнете бросать исключения через границы dll. Это будет работать нормально, если вы выполните некоторые проектные требования в ОС Windows, но не удастся выполнить некоторые другие.

0
ответ дан 17 December 2019 в 18:19
поделиться

Если C API существует и является зрелым, внутренний обход CRT с использованием чистого Win32 API поможет вам на полпути. Другая половина - убедиться, что пользователь DLL использует соответствующие функции Win32 API. Это сделает ваш API менее переносимым как в использовании, так и в документации. Кроме того, даже если вы пойдете по этому пути с распределением памяти, когда и функции CRT, и функции Win32 имеют дело с void *, у вас все еще будут проблемы с файловым материалом - Win32 API использует дескрипторы и ничего не знает о структуре FILE.

Я не совсем уверен, каковы ограничения FILE *, но предполагаю, что проблема такая же, как и с распределением CRT по модулям. MSVCRT использует Win32 внутри для обработки файловых операций, и базовый дескриптор файла может использоваться из каждого модуля в рамках одного процесса. Что может не сработать, так это закрыть файл, который был открыт другим модулем, что включает в себя освобождение структуры FILE на, возможно, другом CRT.

Что бы я сделал, если изменение API все еще возможно, так это экспорт функций очистки для любых возможный «объект», созданный внутри DLL. Эти функции очистки будут обрабатывать удаление данного объекта способом, который соответствует тому, как он был создан в этой DLL. Это также сделает DLL абсолютно переносимой с точки зрения использования. Единственное, что у вас будет в этом случае, - это убедиться, что пользователь DLL действительно использует ваши функции очистки, а не обычные функции CRT. Это можно сделать с помощью нескольких уловок, заслуживающих другого вопроса ...

Что я бы сделал, если изменение API все еще возможно, так это экспортировать функции очистки для любого возможного «объекта», созданного в DLL. Эти функции очистки будут обрабатывать удаление данного объекта способом, который соответствует тому, как он был создан в этой DLL. Это также сделает DLL абсолютно переносимой с точки зрения использования. Единственное, что у вас будет в этом случае, - это убедиться, что пользователь DLL действительно использует ваши функции очистки, а не обычные функции CRT. Это можно сделать с помощью нескольких уловок, заслуживающих другого вопроса ...

Что я бы сделал, если изменение API все еще возможно, так это экспортировать функции очистки для любого возможного «объекта», созданного в DLL. Эти функции очистки будут обрабатывать удаление данного объекта способом, который соответствует тому, как он был создан в этой DLL. Это также сделает DLL абсолютно переносимой с точки зрения использования. Единственное, что у вас будет в этом случае, - это убедиться, что пользователь DLL действительно использует ваши функции очистки, а не обычные функции CRT. Это можно сделать с помощью нескольких уловок, заслуживающих другого вопроса ...

Это также сделает DLL абсолютно переносимой с точки зрения использования. Единственное, что у вас будет в этом случае, - это убедиться, что пользователь DLL действительно использует ваши функции очистки, а не обычные функции CRT. Это можно сделать с помощью нескольких уловок, заслуживающих другого вопроса ...

Это также сделает DLL абсолютно переносимой с точки зрения использования. Единственное, что у вас будет в этом случае, - это убедиться, что пользователь DLL действительно использует ваши функции очистки, а не обычные функции CRT. Это можно сделать с помощью нескольких уловок, заслуживающих другого вопроса ...

0
ответ дан 17 December 2019 в 18:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: