VBA: использование открытого свойства Get вместо Const (для не-Unicode символов)

Я не знаю, что такое Yesod, но я знаю точно , что означает каждая из ваших других ошибок.

Сначала вы должны not попробовать для связывания статически. Предупреждение, которое вы получаете, совершенно правильно: если вы ставите статическую ссылку и используете одну из подпрограмм, для которой вы получаете предупреждение, тогда вы должны организовать запуск в системе с точно той же самой версии libc .so.6 как тот, который вы использовали во время сборки.

Вопреки распространенному мнению, статическая привязка производит less , не более, переносные исполняемые файлы в Linux.

Ваши другие (статические) ошибки ссылок вызваны отсутствием libopenssl.a во время соединения.

Но давайте предположим, что вы собираетесь идти по «нормальному» маршруту и ​​используйте динамическую привязку.

Для динамической компоновки Linux (и большинство других UNIX) поддерживает обратную совместимость: старый двоичный файл продолжает работать на более новых системах. Но они не поддерживают форвардную совместимость (двоичный код, построенный на более новой системе, обычно будет , а не работать на более старом языке.)

Но это то, что вы пытаетесь сделать: вы построенный на системе с glibc-2.14 (или новее), и вы работаете в системе с glibc-2.13 (или старше).

Другое, что вам нужно знать, это то, что glibc состоит из некоторых 200+, которые должны соответствовать точно . Двумя ключевыми двоичными файлами являются /lib/ld-linux.so и /lib/libc.so.6 (но их еще много: libpthread.so.0, libnsl.so.1 и т. Д. И т. Д.). Если некоторые из этих двоичных файлов поступают из разных версий glibc, вы обычно получаете сбой. И это именно то, что вы получили, когда вы попытались поместить свой glibc-2.14 libc.so.6 на LD_LIBRARY_PATH - он больше не соответствует системе /lib/ld-linux.

Итак, каковы решения? Существует несколько возможностей (с большим трудом):

  1. Вы можете скопировать ld-2.14.so (цель символа /lib/ld-linux) в целевую систему и явно вызвать его:
    /path/to/ld-2.14.so --library-path  /path/to/your/executable
    
    Это вообще работает, но может запутать приложение, которое смотрит на argv[0], и ломается для приложений, которые повторно запускают себя.
  2. Вы можете использовать более старую систему.
  3. Вы можете использовать appgcc (этот параметр исчез, см. этот для описания того, чем он был раньше).
  4. Вы можете настроить среду chroot, соответствующую целевой системе, и построить внутри нее chroot.
  5. Вы можете создать себе кросс-компилятор Linux-to-oldLinux

2
задан Moe 15 January 2019 в 17:04
поделиться

1 ответ

Основной проблемой является имя модуля, Constants - оно вводит в заблуждение, поскольку ни общедоступная / глобальная переменная , ни общедоступное свойство get-only не являются константы .

Боковой узел, константы, не назначаемые непостоянным выражениям, не являются ограничением, характерным для VBA.

Свойства являются совершенно допустимыми в стандартных модулях, а общедоступные свойства «только для чтения» - это прекрасный способ показать значение только для чтения, которое необходимо построить во время выполнения.

публичные переменные очищаются при возникновении ошибки или при остановке кода

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

Опять же, для этого не нужно иметь модуль класса, это вполне допустимо в стандартном модуле:

Option Explicit

Public Property Get MyString() As String
    MyString = "\R;;" & Chr(163)
End Property

Если воссоздание строки при каждом обращении к объекту-получателю свойства является проблемой, тогда вам нужен способ сохранить его значение в вспомогательном поле - но тогда это вспомогательное поле (будь то в классе или в стандартном модуле) имеет значение только в том случае, если существует контекст выполнения, то есть у него точно такая же проблема, что и у глобальной переменной было бы: выполнение останавливается, оно ушло.

Одним из обходных путей может быть использование класса с атрибутом VB_PredeclaredId, установленным в True (по умолчанию - False).

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "Class1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Option Explicit

Private internalString As String

Private Sub Class_Initialize()
    internalString = "\R;;" & Chr(163)
End Sub

Public Property Get MyString() As String
    MyString = internalString
End Property

И теперь VBA будет автоматически создавать экземпляр Class1 всякий раз, когда на него ссылаются, , как только на него ссылаются , и этот экземпляр остается «живым», пока оператор End не будет явно выполнен. или контекст выполнения прекращается иным образом. Точно так же, как, скажем, класс UserForm, вы получаете доступ к этому экземпляру по умолчанию , используя имя класса в качестве идентификатора:

Debug.Print Class1.MyString

Если экземпляр по умолчанию существовал при ссылке на Class1 , internalString возвращается. Если этого не произошло, то выполняется Class_Initialize, а затем возвращается internalString.

0
ответ дан Mathieu Guindon 15 January 2019 в 17:04
поделиться
Другие вопросы по тегам:

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