fix(c/sedona-gdal): resolve MEMDataset::Create on GDAL 3.13 + use MEMCreate C-API when available#963
Conversation
GDAL 3.13 changed MEMDataset::Create's final parameter from char** to char const* const*, which changes the Itanium-ABI mangled symbol name (…GDALDataTypePPc -> …GDALDataTypePKS1_). The dynamic loader's candidate list only had the <=3.12 name, so the MEM dataset bridge failed at runtime with "Failed to resolve MEMDatasetCreate under any known mangled name" on GDAL 3.13. Add the 3.13 mangled name; pointer constness doesn't affect the call ABI.
paleolimbot
left a comment
There was a problem hiding this comment.
The const changes the mangling of the C++ name; however, Kristin added this to the C API which I believe was also released in 3.13 ( OSGeo/gdal#14108 ).
This may need a similar change for MSVC mangling, but we can/should probably go straight to the C symbol if it exists (now that there is one).
|
Each time the constness of pointer parameter changes, the ABI breaks. Fortunatelly the upstream accepted our request of adding |
…taset::Create
Resolving MEMDataset::Create by its C++ mangled name is brittle: the mangling
depends on the platform and on parameter constness, so it changed in GDAL 3.13
(char** -> char const* const*) and will change again for future GDAL, panicking
at load time ("Failed to resolve ... under any known mangled name").
GDAL now exports MEMCreate as a stable public C API. Resolve it first — it takes
no filename parameter, so it gets its own fn-pointer type and call path — and
fall back to the mangled MEMDataset::Create only when MEMCreate is absent (older
GDAL). Error only if neither resolves. This keeps the dynamic loader robust
across current and future GDAL versions.
Verified against GDAL 3.13.1 (cargo test -p sedona-gdal --features gdal-sys/bindgen
-> 102 passed).
paleolimbot
left a comment
There was a problem hiding this comment.
I checked with local GDAL 3.13 and specifically checked that the new C symbol was getting used and this works great! Thank you!
I'm not really sure what this does but it makes it so that GDAL 3.13 doesnt break the build/runtime anymore.
I integrated the fix Kristin recommended below as well
Summary (AI-generated)
The GDAL MEM-dataset bridge resolves the MEM
Createentry point dynamically inc/sedona-gdal/src/dyn_load.rs. It originally relied solely on the C++MEMDataset::Createsymbol, looked up by its mangled name. That mangling is fragile — it depends on the platform and on the parameters' constness — so GDAL 3.13 changed the final parameter fromchar**tochar const* const*(…GDALDataTypePPc→…GDALDataTypePKS1_), the candidate list only had the ≤3.12 name, and the bridge panicked at load time ("Failed to resolve … under any known mangled name"), breaking every GDAL raster op. Each future re-mangling would break it again.GDAL has since added
MEMCreateas a stable, unmangled public C API. This change resolvesMEMCreatefirst and falls back to the mangledMEMDataset::Createonly when it is absent (older GDAL), erroring only if neither resolves. BecauseMEMCreatedrops thepszFilenameparameter, it gets its own fn-pointer type and call path:create_mem_datasetcallsMEMCreate(no filename) when present, otherwise the mangled C++ method with a leading empty filename.Verified against a local GDAL 3.13.1 install:
cargo test -p sedona-gdal --features gdal-sys/bindgen→ 102 passed.