问题
This is related to Assigning events to a VCL control created dynamically at runtime.
I used the above listed/reference post to solve a problem that I had with some code. Thank you for providing that example. I found it very useful, and implemented the "alternative" way that it provided as I was unable to make the first way work.
I am using C++Builder 10.x from Embarcadero. I just updated to C++Builder 10.3. This new update is now throwing a warning:
[bcc32c Warning] LogitToMemo.cpp(196): implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension
The line it is throwing on is:
Method.Code = &LogLevelComboBoxOnChange;
I am not sure how to "fix" this.
The code is in support of a logging function to a memo field, where the page for the logging memo has a TComboBox to select the logging level/verbosity.
The TComboBox is external to the logging function, as it is on the user's form. I want the TComboBox::OnChange event to call my LogLevelComboBoxOnChange function, which adjusts the logging level based on the TComboBox item/entry selected.
Supporting code around this includes.
Function declaration - TComboBox::OnChange Event Function
void __fastcall LogLevelComboBoxOnChange(void *pThis, TObject *Sender);
Function Declaration - Logging start up where the TMemo field to log to & the TComboBox are provided
int LogStartWithComboBox(TMemo *LogIt_MemoField, TComboBox *AppLogLevelComboBox, int iThreshold, AnsiString &asFieldTitles);
This is the function that assigns the OnChange function to the TComboBox object on the user's logging form.
int LogStartWithComboBox(TMemo *LogIt_MemoField, TComboBox *AppLogLevelComboBox, int iThreshold, AnsiString &asFieldTitles)
{
static TMethod Method;
//
// Set-Up CombBox and OnChange Event
// - Save ComboBox pointer
// - Assign List of Log Levels
// - Assign/Set-Up OnChange Function
//
LogLevelComboBox = AppLogLevelComboBox;
AppLogLevelComboBox->Items->Text =
"Off\n"
"All Messages\n"
"Verbose\n"
"Trace\n"
"Informational\n"
"Warning\n"
"Error\n"
"Severe\n"
"Fatal";
AppLogLevelComboBox->ItemIndex = iThreshold + 1;
//
// Set-Up - On Change Function for "external" Log Level Combo-Box
//
Method.Data = NULL; // passed to the pThis parameter, can be whatever you want
//
// The Following line generates the warning
// [bcc32c Warning] LogitToMemo.cpp(196): implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension
//
Method.Code = &LogLevelComboBoxOnChange;
LogLevelComboBox->OnChange = reinterpret_cast<TNotifyEvent&>(Method);
return 0;
}
回答1:
You are using C++Builder's CLang-based C++ compiler. The "implicit conversion" warning you are seeing is a CLang issue that has cropped up during the past few years in multiple toolchains that use CLang, not just in C++Builder. This issue does not affect C++Builder's "classic" (non-CLang) compiler.
&LogLevelComboBoxOnChange creates a pointer-to-function, which CLang does not like to implicitly convert to void* (which is what the TMethod::Code field is declared as) unless Clang is put into a Microsoft compatibility mode.
Possible solutions are to either:
type-cast the pointer explicitly:
(UPDATE: apparently CLang doesn't like static_casting a pointer-to-function to
void*, either!)Method.Code = static_cast<void*>(&LogLevelComboBoxOnChange);Method.Code = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(&LogLevelComboBoxOnChange));enable the
-Wmicrosoft-castflag in the CLang compiler settings.disable the warning in your code by using
#pragmastatements around the assignment toMethod.Code:#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmicrosoft-cast" Method.Code = &LogLevelComboBoxOnChange; #pragma clang diagnostic popuse a
union(though, I'm sure some people will argue that this probably violates Strict Aliasing rules, but if it works...):union { void (__fastcall *func)(void*, TObject*); void *ptr; } u; u.func = &LogLevelComboBoxOnChange; Method.Code = u.ptr;
来源:https://stackoverflow.com/questions/54330724/assigning-events-to-a-vcl-control-created-dynamically-at-runtime-2