Skip to content

Commit 841ec0d

Browse files
shai-almogclaude
andcommitted
Windows port: drop C++ STL from WinRT natives (cross-compile fix)
The Linux cross-compile failed compiling cn1_windows_winrt.cpp: the <string> I used for the contacts/share string building pulls the MSVC STL (yvals_core.h), which hard-asserts a very recent Clang (STL1000) that the xwin cross-toolchain predates. The rest of the port is deliberately STL-free for exactly this reason (cn1_windows_browser.cpp's std:: usage is behind the WebView2 gate, off on the cross-compile). Replace std::string/std::wstring with a small C growable buffer (CN1Buf) and owned WCHAR* so no C++ STL header is pulled (verified via /showIncludes: zero STL headers, only the C <string.h>). clean-target (real Windows, newer clang) already passed; this unblocks the cross-compile gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 22d955b commit 841ec0d

1 file changed

Lines changed: 74 additions & 25 deletions

File tree

Ports/WindowsPort/nativeSources/cn1_windows_winrt.cpp

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
#ifdef CN1_HAVE_WINRT
4444

4545
#include <roapi.h>
46-
#include <string>
46+
#include <stdlib.h>
47+
#include <string.h>
4748
#include <wrl.h>
4849
#include <wrl/event.h>
4950
#include <wrl/wrappers/corewrappers.h>
@@ -102,8 +103,47 @@ static void cn1WinRtInit() {
102103
RoInitialize(RO_INIT_MULTITHREADED);
103104
}
104105

105-
/* Appends the UTF-8 bytes of an HSTRING to `out` (empty HSTRING -> nothing). */
106-
static void cn1AppendHString(std::string& out, HSTRING h) {
106+
/* A minimal growable UTF-8 byte buffer. The port avoids the C++ STL (the MSVC STL
107+
* headers hard-require a very recent Clang, which the cross-compile toolchain may
108+
* predate), so contacts/share string building uses this instead of std::string. */
109+
typedef struct CN1Buf {
110+
char* data;
111+
size_t len;
112+
size_t cap;
113+
} CN1Buf;
114+
115+
static void cn1BufInit(CN1Buf* b) {
116+
b->data = NULL;
117+
b->len = 0;
118+
b->cap = 0;
119+
}
120+
121+
static void cn1BufAppendBytes(CN1Buf* b, const char* src, size_t n) {
122+
if (b->len + n + 1 > b->cap) {
123+
size_t want = (b->cap == 0 ? 256 : b->cap * 2);
124+
while (want < b->len + n + 1) {
125+
want *= 2;
126+
}
127+
char* grown = (char*) realloc(b->data, want);
128+
if (grown == NULL) {
129+
return;
130+
}
131+
b->data = grown;
132+
b->cap = want;
133+
}
134+
if (src != NULL && n > 0) {
135+
memcpy(b->data + b->len, src, n);
136+
}
137+
b->len += n;
138+
b->data[b->len] = 0;
139+
}
140+
141+
static void cn1BufAppendChar(CN1Buf* b, char c) {
142+
cn1BufAppendBytes(b, &c, 1);
143+
}
144+
145+
/* Appends the UTF-8 bytes of an HSTRING to the buffer (empty HSTRING -> nothing). */
146+
static void cn1AppendHString(CN1Buf* out, HSTRING h) {
107147
UINT32 len = 0;
108148
PCWSTR w = WindowsGetStringRawBuffer(h, &len);
109149
if (w == NULL || len == 0) {
@@ -113,9 +153,13 @@ static void cn1AppendHString(std::string& out, HSTRING h) {
113153
if (n <= 0) {
114154
return;
115155
}
116-
size_t at = out.size();
117-
out.resize(at + (size_t) n);
118-
WideCharToMultiByte(CP_UTF8, 0, w, (int) len, &out[at], n, NULL, NULL);
156+
char* tmp = (char*) malloc((size_t) n);
157+
if (tmp == NULL) {
158+
return;
159+
}
160+
WideCharToMultiByte(CP_UTF8, 0, w, (int) len, tmp, n, NULL, NULL);
161+
cn1BufAppendBytes(out, tmp, (size_t) n);
162+
free(tmp);
119163
}
120164

121165
#endif /* CN1_HAVE_WINRT */
@@ -302,14 +346,15 @@ JAVA_OBJECT com_codename1_impl_windows_WindowsNative_contactsGetAll___R_java_lan
302346
}
303347
unsigned int size = 0;
304348
contacts->get_Size(&size);
305-
std::string blob;
349+
CN1Buf blob;
350+
cn1BufInit(&blob);
306351
for (unsigned int i = 0; i < size; i++) {
307352
ComPtr<IContact> c;
308353
if (FAILED(contacts->GetAt(i, &c)) || !c) {
309354
continue;
310355
}
311356
if (i > 0) {
312-
blob.push_back('\x1e');
357+
cn1BufAppendChar(&blob, '\x1e');
313358
}
314359
/* Name is on the base IContact; Id / Phones / Emails on IContact2. */
315360
HString name;
@@ -320,10 +365,10 @@ JAVA_OBJECT com_codename1_impl_windows_WindowsNative_contactsGetAll___R_java_lan
320365
if (c2) {
321366
c2->get_Id(id.GetAddressOf());
322367
}
323-
cn1AppendHString(blob, id.Get());
324-
blob.push_back('\x1f');
325-
cn1AppendHString(blob, name.Get());
326-
blob.push_back('\x1f');
368+
cn1AppendHString(&blob, id.Get());
369+
cn1BufAppendChar(&blob, '\x1f');
370+
cn1AppendHString(&blob, name.Get());
371+
cn1BufAppendChar(&blob, '\x1f');
327372
/* first phone number */
328373
if (c2) {
329374
ComPtr<IVector<ContactPhone*>> phones;
@@ -335,12 +380,12 @@ JAVA_OBJECT com_codename1_impl_windows_WindowsNative_contactsGetAll___R_java_lan
335380
if (SUCCEEDED(phones->GetAt(0, &phone)) && phone) {
336381
HString num;
337382
phone->get_Number(num.GetAddressOf());
338-
cn1AppendHString(blob, num.Get());
383+
cn1AppendHString(&blob, num.Get());
339384
}
340385
}
341386
}
342387
}
343-
blob.push_back('\x1f');
388+
cn1BufAppendChar(&blob, '\x1f');
344389
/* first email */
345390
if (c2) {
346391
ComPtr<IVector<ContactEmail*>> emails;
@@ -352,13 +397,17 @@ JAVA_OBJECT com_codename1_impl_windows_WindowsNative_contactsGetAll___R_java_lan
352397
if (SUCCEEDED(emails->GetAt(0, &email)) && email) {
353398
HString addr;
354399
email->get_Address(addr.GetAddressOf());
355-
cn1AppendHString(blob, addr.Get());
400+
cn1AppendHString(&blob, addr.Get());
356401
}
357402
}
358403
}
359404
}
360405
}
361-
return newStringFromCString(threadStateData, blob.c_str());
406+
{
407+
JAVA_OBJECT s = newStringFromCString(threadStateData, blob.data != NULL ? blob.data : "");
408+
free(blob.data);
409+
return s;
410+
}
362411
#else
363412
return JAVA_NULL;
364413
#endif
@@ -373,20 +422,20 @@ JAVA_OBJECT com_codename1_impl_windows_WindowsNative_contactsGetAll___R_java_lan
373422
* stashed in file-static state read by the (same-thread) DataRequested handler.
374423
* Shares text (the common case); image-file sharing is a later addition. */
375424
#ifdef CN1_HAVE_WINRT
376-
static std::wstring g_shareText;
377-
static std::wstring g_shareTitle;
425+
static WCHAR* g_shareTextW = NULL;
426+
static WCHAR* g_shareTitleW = NULL;
378427
static bool g_shareHandlerRegistered = false;
379428
static ComPtr<IDataTransferManager> g_shareDtm;
380429
#endif
381430

382431
void cn1WinShareHandleMessage(WPARAM wParam) {
383432
#ifdef CN1_HAVE_WINRT
384-
/* wParam carries [textW, titleW] copied by the caller; take ownership. */
433+
/* wParam carries [textW, titleW] allocated by the caller; take ownership. */
385434
WCHAR** data = (WCHAR**) wParam;
386-
g_shareText = data[0] != NULL ? data[0] : L"";
387-
g_shareTitle = data[1] != NULL ? data[1] : L"";
388-
if (data[0] != NULL) { free(data[0]); }
389-
if (data[1] != NULL) { free(data[1]); }
435+
if (g_shareTextW != NULL) { free(g_shareTextW); }
436+
if (g_shareTitleW != NULL) { free(g_shareTitleW); }
437+
g_shareTextW = data[0];
438+
g_shareTitleW = data[1];
390439
free(data);
391440
if (cn1Win.hwnd == NULL) {
392441
return;
@@ -417,9 +466,9 @@ void cn1WinShareHandleMessage(WPARAM wParam) {
417466
ComPtr<IDataPackagePropertySet> props;
418467
if (SUCCEEDED(pkg->get_Properties(&props)) && props) {
419468
props->put_Title(HStringReference(
420-
g_shareTitle.empty() ? L"Share" : g_shareTitle.c_str()).Get());
469+
(g_shareTitleW != NULL && g_shareTitleW[0] != 0) ? g_shareTitleW : L"Share").Get());
421470
}
422-
pkg->SetText(HStringReference(g_shareText.c_str()).Get());
471+
pkg->SetText(HStringReference(g_shareTextW != NULL ? g_shareTextW : L"").Get());
423472
return S_OK;
424473
}).Get(),
425474
&token);

0 commit comments

Comments
 (0)