Как я могу предотвратить сборщик мусора от вмешательства в память, выделенную делегату [duplicate]

Использовать Apache HTTP для SDK уровня 23:

Top level build.gradle - /build.gradle

buildscript {
    ...
    dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0' 
        // Lowest version for useLibrary is 1.3.0
        // Android Studio will notify you about the latest stable version
        // See all versions: http://jcenter.bintray.com/com/android/tools/build/gradle/
    }
    ...
}

Уведомление от студии Android о обновлении градиента:

Тип модуля build.gradle - /app/build.gradle

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
    ...
    useLibrary 'org.apache.http.legacy'
    ...
}

15
задан John Saunders 4 September 2011 в 22:40
поделиться

2 ответа

    channel.setCallback(channelCallback);

Это проблема. FMod - неуправляемый код. Здесь вы создаете объект-делегат и передаете его неуправляемому коду. Проблема в том, что сборщик мусора не может отслеживать ссылки, хранящиеся в собственном коде. Следующая мусорная коллекция найдет no ссылки на объект и соберет его. Kaboom, когда нативный код выполняет обратный вызов.

Вам нужно сохранить ссылку самостоятельно, чтобы этого не произошло:

public class Music
{
    private SomeDelegateType callback
    //...
    public Music(string file)
    {
        File = file;
        callback = new SomeDelegateType(channelCallback);
    }

    public virtual void Play()
    {
        Audio.System.playSound(channel == null ? CHANNELINDEX.FREE : CHANNELINDEX.REUSE, music, false, ref channel);
        music.addSyncPoint(500, TIMEUNIT.MS, "wooo", ref syncPtr);
        channel.setCallback(callback);
    }

Вам нужно найти фактический тип делегата из Код обертки FMod, я просто догадывался о «SomeDelegateType».

23
ответ дан Hans Passant 18 August 2018 в 12:38
поделиться
  • 1
    Ах, ладно, спасибо, это было непонимание того, как делегаты работают с моей стороны тогда. – Matt 4 September 2011 в 22:40
  • 2
    Делегат - это объект в своем собственном праве. Это иногда скрывается синтаксисом ярлыка, поддерживаемым с C # 2.0, где компилятор выполняет преобразование от вашего имени. В вашем случае код channel.setCallback(channelCallback); преобразуется компилятором в channel.setCallback(new SomeDelegateType(channelCallback));. – Bevan 4 September 2011 в 22:45
  • 3
    Мои комплименты по вопросу btw, вы упростили вам помощь. Отличное описание проблемы, отправляя точно правильный код. +1. – Hans Passant 4 September 2011 в 23:05

У меня была аналогичная проблема между VB.NET и пользовательской C ++ DLL. Исправлено благодаря @Hans. Я много раз обязан этому сайту для всех проблем, с которыми мне пришлось пройти. Добавляем решение проблемы + в надежде, что он помогает другим видеть одно и то же решение в другом контексте.

Объявил это (в модуле)

Public Delegate Sub CB_FUNC(ByVal x As Integer, ByVal y As Integer)
Public Declare Sub vidProc_cb_MouseClick Lib "C:\Users\.....\vidProc\product\vidProc.dll" (ByVal addr_update As CB_FUNC)

Первоначально:

Имел простой вызов в кнопке button_click:

vidProc_cb_MouseClick(AddressOf updateXY)

Я бы получил ошибку «CallbackOnCollectedDelegate». Не сразу, но после взаимодействия с другими объектами в форме, а затем пытается вызвать обратный вызов (который в моем случае был щелчком мыши в окне OpenCV).

Исправлено:

1) Объявление (в классе формы, декларации)

Private addr_update As CB_FUNC

2) Определение addr_update для формы Load

addr_update = New CB_FUNC(AddressOf updateXY)

3) Вызов функции «set callback» с помощью функции новый указатель (в кнопке button_click)

vidProc_cb_MouseClick(addr_update)

Я думаю, что понял @Hans и внедрил его правильно (я не могу воспроизвести ошибку). Надеюсь, это кому-то поможет.

0
ответ дан cBiscuit 18 August 2018 в 12:38
поделиться
Другие вопросы по тегам:

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