Skip to content

Commit 10677d4

Browse files
committed
flatlaf-natives-windows: fixed link error on GitHub Actions
for some unknown reason (maybe newer Visual C++ version), MSVC on GitHub Actions no longer inlines methods `wcscpy` and `wcslen`, which results in linker error: `error LNK2019: unresolved external symbol wcscpy/wcslen`
1 parent df8212b commit 10677d4

3 files changed

Lines changed: 35 additions & 17 deletions

File tree

flatlaf-natives/flatlaf-natives-windows/src/main/cpp/Runtime.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,16 @@ int __cdecl printf( const char* format, ... ) {
8383
return retValue;
8484
}
8585
*/
86+
87+
size_t rt_wcslen( const wchar_t* str ) {
88+
const wchar_t* s = str;
89+
while( *s != '\0' )
90+
s++;
91+
return (size_t) (s - str);
92+
}
93+
94+
void rt_wcscpy( wchar_t* dest, const wchar_t* src ) {
95+
while( *src != '\0' )
96+
*dest++ = *src++;
97+
*dest = '\0';
98+
}

flatlaf-natives/flatlaf-natives-windows/src/main/cpp/WinFileChooser.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
// declare external methods
3131
extern HWND getWindowHandle( JNIEnv* env, jobject window );
32+
extern size_t rt_wcslen( const wchar_t* str );
3233

3334
// declare internal methods
3435
static jobjectArray getFiles( JNIEnv* env, jboolean open, IFileDialog* dialog );
@@ -202,7 +203,7 @@ static jobjectArray newJavaStringArray( JNIEnv* env, jsize count ) {
202203
}
203204

204205
static jstring newJavaString( JNIEnv* env, LPWSTR str ) {
205-
return env->NewString( reinterpret_cast<jchar*>( str ), static_cast<jsize>( wcslen( str ) ) );
206+
return env->NewString( reinterpret_cast<jchar*>( str ), static_cast<jsize>( rt_wcslen( str ) ) );
206207
}
207208

208209
//---- JNI methods ------------------------------------------------------------

flatlaf-natives/flatlaf-natives-windows/src/main/cpp/WinMessageDialog.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
// declare external fields
3333
extern HINSTANCE _instance;
3434

35+
// declare external methods
36+
extern size_t rt_wcslen( const wchar_t* str );
37+
extern void rt_wcscpy( wchar_t* dest, const wchar_t* src );
38+
3539
// declare internal methods
3640
static byte* createInMemoryTemplate( HWND owner, int messageType, LPCWSTR title, LPCWSTR text,
3741
int defaultButton, int buttonCount, LPCWSTR* buttons );
@@ -154,8 +158,8 @@ static byte* createInMemoryTemplate( HWND owner, int messageType, LPCWSTR title,
154158
int th = 0;
155159
if( text == NULL )
156160
text = L"";
157-
LPWSTR wrappedText = new WCHAR[wcslen( text ) + 1];
158-
wcscpy( wrappedText, text );
161+
LPWSTR wrappedText = new WCHAR[rt_wcslen( text ) + 1];
162+
rt_wcscpy( wrappedText, text );
159163
LPWSTR lineStart = wrappedText;
160164
for( LPWSTR t = wrappedText; ; t++ ) {
161165
if( *t != '\n' && *t != 0 )
@@ -193,11 +197,11 @@ static byte* createInMemoryTemplate( HWND owner, int messageType, LPCWSTR title,
193197
th += LABEL_HEIGHT;
194198

195199
// duplicate string
196-
LPWSTR wrappedText2 = new WCHAR[wcslen( wrappedText ) + 1 + 1];
200+
LPWSTR wrappedText2 = new WCHAR[rt_wcslen( wrappedText ) + 1 + 1];
197201
// use wcscpy(), instead of wcsncpy(), because this method is inlined and does not require linking to runtime lib
198-
wcscpy( wrappedText2, wrappedText );
202+
rt_wcscpy( wrappedText2, wrappedText );
199203
wrappedText2[breakIndex] = '\n';
200-
wcscpy( wrappedText2 + breakIndex + 1, wrappedText + breakIndex );
204+
rt_wcscpy( wrappedText2 + breakIndex + 1, wrappedText + breakIndex );
201205

202206
// delete old text
203207
delete[] wrappedText;
@@ -262,11 +266,11 @@ static byte* createInMemoryTemplate( HWND owner, int messageType, LPCWSTR title,
262266
// (approximately) calculate memory size needed for in-memory template
263267
int templSize = (sizeof(DLGTEMPLATE) + /*menu*/ 2 + /*class*/ 2 + /*title*/ 2)
264268
+ ((sizeof(DLGITEMTEMPLATE) + /*class*/ 4 + /*title/icon*/ 4 + /*creation data*/ 2) * (/*icon+text*/2 + buttonCount))
265-
+ (title != NULL ? (wcslen( title ) + 1) * sizeof(wchar_t) : 0)
266-
+ /*fontPointSize*/ 2 + ((wcslen( fontFaceName ) + 1) * sizeof(wchar_t))
267-
+ ((wcslen( wrappedText ) + 1) * sizeof(wchar_t));
269+
+ (title != NULL ? (rt_wcslen( title ) + 1) * sizeof(wchar_t) : 0)
270+
+ /*fontPointSize*/ 2 + ((rt_wcslen( fontFaceName ) + 1) * sizeof(wchar_t))
271+
+ ((rt_wcslen( wrappedText ) + 1) * sizeof(wchar_t));
268272
for( int i = 0; i < buttonCount; i++ )
269-
templSize += ((wcslen( buttons[i] ) + 1) * sizeof(wchar_t));
273+
templSize += ((rt_wcslen( buttons[i] ) + 1) * sizeof(wchar_t));
270274

271275
templSize += (2 * (1 + 1 + buttonCount)); // necessary for DWORD alignment
272276
templSize += 100; // some reserve
@@ -291,15 +295,15 @@ static byte* createInMemoryTemplate( HWND owner, int messageType, LPCWSTR title,
291295
*lpw++ = 0; // no menu
292296
*lpw++ = 0; // predefined dialog box class (by default)
293297
if( title != NULL ) {
294-
wcscpy( (LPWSTR) lpw, title );
295-
lpw += wcslen( title ) + 1;
298+
rt_wcscpy( (LPWSTR) lpw, title );
299+
lpw += rt_wcslen( title ) + 1;
296300
} else
297301
*lpw++ = 0; // no title
298302

299303
// for DS_SETFONT
300304
*lpw++ = fontPointSize;
301-
wcscpy( (LPWSTR) lpw, fontFaceName );
302-
lpw += wcslen( fontFaceName ) + 1;
305+
rt_wcscpy( (LPWSTR) lpw, fontFaceName );
306+
lpw += rt_wcslen( fontFaceName ) + 1;
303307

304308
//---- define icon ----
305309

@@ -335,7 +339,7 @@ static byte* createInMemoryTemplate( HWND owner, int messageType, LPCWSTR title,
335339

336340
lpw = (LPWORD) (lpdit + 1);
337341
*lpw++ = 0xffff; *lpw++ = 0x0082; // Static class
338-
wcscpy( (LPWSTR) lpw, wrappedText ); lpw += wcslen( wrappedText ) + 1; // text
342+
rt_wcscpy( (LPWSTR) lpw, wrappedText ); lpw += rt_wcslen( wrappedText ) + 1; // text
339343
*lpw++ = 0; // creation data
340344

341345

@@ -356,7 +360,7 @@ static byte* createInMemoryTemplate( HWND owner, int messageType, LPCWSTR title,
356360

357361
lpw = (LPWORD) (lpdit + 1);
358362
*lpw++ = 0xffff; *lpw++ = 0x0080; // Button class
359-
wcscpy( (LPWSTR) lpw, buttons[i] ); lpw += wcslen( buttons[i] ) + 1; // text
363+
rt_wcscpy( (LPWSTR) lpw, buttons[i] ); lpw += rt_wcslen( buttons[i] ) + 1; // text
360364
*lpw++ = 0; // creation data
361365

362366
bx += bw[i] + BUTTON_GAP;
@@ -394,7 +398,7 @@ static INT_PTR CALLBACK messageDialogProc( HWND hwnd, UINT uMsg, WPARAM wParam,
394398

395399
static int textLengthAsDLUs( HDC hdc, LPCWSTR str, int strLen ) {
396400
SIZE size{ 0 };
397-
::GetTextExtentPoint32( hdc, str, (strLen >= 0) ? strLen : wcslen( str ), &size );
401+
::GetTextExtentPoint32( hdc, str, (strLen >= 0) ? strLen : rt_wcslen( str ), &size );
398402
return pixel2dluX( size.cx );
399403
}
400404

0 commit comments

Comments
 (0)