<div dir="ltr">I unfortunately can't just give away what I did, but I wrote my own C# wrapper for proj.<div><br></div><div>I followed the instructions on the webpage over here:<br><a href="https://proj.org/install.html#building-on-windows-with-vcpkg-and-visual-studio-2017-or-2019">https://proj.org/install.html#building-on-windows-with-vcpkg-and-visual-studio-2017-or-2019</a><br></div><div><br></div><div>If you didn't put vcpkg at c:\dev\vcpkg, just make a symlink and it should work fine. Just be sure to run all related vcpkg install commands from the original directory.</div><div><br></div><div>To build debug vs release, I use these commands in the x64 Native Tools command prompt:</div><div>cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=C:\dev\vcpkg\scripts\buildsystems\vcpkg.cmake ..<br>cmake --build . --config Debug -j 8<br></div><div><br></div><div>cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=C:\dev\vcpkg\scripts\buildsystems\vcpkg.cmake ..<br>cmake --build . --config Release -j 8<br></div><div><br></div><div>Beyond that, I forked the regular proj repo to add/modify a few things, and I have a C# wrapper DLL that handles the P/Invoke calls. Additionally, we generate a pair of internal Nuget packages. One contains the dll references only. It'll put the following DLLs in runtimes/win-x64/native:</div><div>jpeg62.dll, libcurl.dll, "proj dll output from the build", "my custom C proj dll", lzma.dll, sqlite3.dll, tiff.dll, and zlib1.dll.</div><div><br></div><div>Similarly we've got a linux equivalent that does runtimes/linux-x64 and linux-arm64.</div><div><br></div><div>The second nuget package is the proj.db and friends that appear in the data folder after building proj: alaska, BETA2007.gsb, conus, egm96_15.gtx, GL27, ITRF2000, MD, nad27, nad83, ntf_r93.gsb, ntv1_can.dat, ntv2_0.gsb, proj.db, and proj.ini. When I create a proj context object, I make sure to give it their path via SetSearchPaths.</div><div><br></div><div>You don't necessarily need nuget packages if you do a post build copy step or something along those lines.</div><div><br></div><div><div>In my custom C++ code I made a whole set of methods to ensure that all strings are CoTaskMemAlloc'd so they happily marshal to the .NET world. It was a bit of a pain to do, but I don't get random crashes dealing with strings anymore. I also added methods for instantiating certain unmanaged objects so I can get at their memory address.</div></div><div><br></div><div>In the C# wrapper, I set up a system like this. I have ProjObjects and ProjHandles whose main job is to make sure everything gets disposed properly. The only hitch is dealing with the default ProjContext and making sure not to ever kill that.</div><div><br></div><div>public abstract class ProjObject : IDisposable {<br><br>       private bool isDisposed;<br>      public bool IsDisposed { get => isDisposed; }<br><br>    public void Dispose() {<br>               if (this.isDisposed)<br>                  return;<br><br>             this.DisposeCore();<br>           this.isDisposed = true;<br>       }<br>     protected virtual void DisposeCore() { }<br>}<br><br>public abstract class ProjHandleObject<T> : ProjObject, IProjHandleObject<T> where T : ProjSafeHandle {<br><br>  protected readonly T handle;<br>  internal T Handle => handle;<br>       T IProjHandleObject<T>.Handle => handle;<br><br>   public IntPtr UnsafeAddress => Handle.DangerousGetHandle();<br><br>      public virtual bool IsValid => !handle.IsInvalid;<br><br>        internal ProjHandleObject(T handle) => this.handle = handle ?? throw new ArgumentNullException(nameof(handle));<br><br>  protected override void DisposeCore() {<br>               this.handle.Dispose();<br><br>              base.DisposeCore();<br>   }<br><br>}<br><br>public interface IProjObject : IDisposable {<br><br>      bool IsDisposed { get; }<br>      bool IsValid { get; }<br><br>}<br>internal interface IProjHandleObject<T> : IProjObject where T : ProjSafeHandle {<br><br><br>        T Handle { get; }<br><br>}<br><br>public abstract class ProjSafeHandle : SafeHandle {<br><br>       public override bool IsInvalid => handle.ToInt64() == 0;<br><br> protected ProjSafeHandle() : base(IntPtr.Zero, true) { }<br>      protected ProjSafeHandle(bool ownsHandle) : base(IntPtr.Zero, ownsHandle) { }<br><br>}<br><br>Here's an actual sample object w/ handle:<br>public class ProjTypesArray : ProjHandleObject<ProjTypesArrayHandle> {<br><br>   private readonly int length;<br>  public int Length => length;<br><br>     [System.Diagnostics.DebuggerStepThrough]<br>      internal ProjTypesArray(ProjTypesArrayHandle handle, int length) : base(handle) {<br>             this.length = length;<br> }<br><br>}<br><br>public class ProjTypesArrayHandle : ProjSafeHandle {<br><br>      [System.Diagnostics.DebuggerStepThrough]<br>      internal ProjTypesArrayHandle() { }<br><br> protected override bool ReleaseHandle() {<br>             //No other verification other than it doesn't die.<br>                Api.ProjProxy.Iso.CrsList.projproxy_destroy_unmanaged_pj_types_array(this.handle);<br>            return true;<br>  }<br><br>}<br><br>PInvoke call looks like this:<br>[DllImport(PROJ_PROXY_DLL, EntryPoint = "projproxy_create_unmanaged_pj_types_array", CallingConvention = CallingConvention.Cdecl)]<br>public extern static ProjTypesArrayHandle projproxy_create_unmanaged_pj_types_array(PJ_TYPE[] types, long typesCount);<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jan 5, 2023 at 6:31 AM Bert Huijben <<a href="mailto:bert@qqmail.nl">bert@qqmail.nl</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="msg4735443175114634948"><div lang="NL" style="overflow-wrap: break-word;"><div class="m_4735443175114634948WordSection1"><p class="MsoNormal"><span lang="EN-US">When I tried to use proj from C# a few years back I created a wrapper library SharpProj (<a href="https://github.com/AmpScm/SharpProj.git" target="_blank">https://github.com/AmpScm/SharpProj.git</a>)<u></u><u></u></span></p><p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p><p class="MsoNormal"><span lang="EN-US">All sourcecode and buildscripts that work for me are in the repository, but I’m guessing you can just use NuGet and use the latest proj directly with some of the sample code from there.<u></u><u></u></span></p><p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p><p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p><p class="MsoNormal"><span lang="EN-US">The easiest way to build proj yourself on Windows is current most likely using vcpkg. That helps building proj and all its dependencies.<u></u><u></u></span></p><p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p><p class="MsoNormal"><span lang="EN-US">               Bert<u></u><u></u></span></p><p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p><div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(225,225,225);padding:3pt 0cm 0cm"><p class="MsoNormal"><b><span lang="EN-US">From:</span></b><span lang="EN-US"> PROJ <<a href="mailto:proj-bounces@lists.osgeo.org" target="_blank">proj-bounces@lists.osgeo.org</a>> <b>On Behalf Of </b>Jonathan Johansen<br><b>Sent:</b> Thursday, January 5, 2023 4:08 AM<br><b>To:</b> <a href="mailto:proj@lists.osgeo.org" target="_blank">proj@lists.osgeo.org</a><br><b>Subject:</b> [PROJ] Interface to PROJ from C#<u></u><u></u></span></p></div><p class="MsoNormal"><span lang="EN-US"><u></u> <u></u></span></p><div><p class="MsoNormal">Hi all!<u></u><u></u></p><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">I'm trying to use PROJ 9.1.1 in my C# Windows project, but am not having any success. A friend has tried to use it from EasyGIS, but ran into an issue. So I thought I'd try SharpProj (<a href="https://github.com/AmpScm/SharpProj" target="_blank">https://github.com/AmpScm/SharpProj</a>), but I ran into <a href="https://github.com/AmpScm/SharpProj/issues/25" target="_blank">https://github.com/AmpScm/SharpProj/issues/25</a>. So I thought why not try to use the win DLL directly myself? So I got the 64 bit OSGeo4W from <a href="https://proj.org/install.html#windows" target="_blank">https://proj.org/install.html#windows</a>, and grabbed all of the DLLs in the bin folder, and have put them into my project. But it throws a similar error:<u></u><u></u></p></div><div><p class="MsoNormal">>'Unable to load DLL 'proj_9_1.dll' or one of its dependencies: The specified module could not be found.<u></u><u></u></p></div><div><p class="MsoNormal">So I thought I'd try to build the DLLS myself and use them. So I've got the 9.1.1 source code, installed cmake, started going through the first tutorial, and am trying. I'm not familiar with Linux, and I'm building on Windows (I see one entry in the mailing list from June 2022 about windows), so this is probably not going to be easy. Anyway, when trying to build it, I get this:<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">>D:\Downloads\proj_build>cmake ../proj-9.1.1<br>-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19045.<br>-- Requiring C++11<br>-- Requiring C++11 - done<br>-- Requiring C99<br>-- Requiring C99 - done<br>-- Configuring PROJ:<br>-- PROJ_VERSION                   = 9.1.1<br>-- PROJ_ABI_VERSION               = 9_1<br>CMake Warning at cmake/ProjConfig.cmake:48 (message):<br>  Autoconf's D:/Downloads/proj-9.1.1/src/proj_config.h may interfere with<br>  this CMake build.  Run 'make distclean' in the source directory before<br>  CMake's build.<br>Call Stack (most recent call first):<br>  CMakeLists.txt:127 (include)<br><br>-- nlohmann/json: internal<br>CMake Error at CMakeLists.txt:176 (message):<br>  sqlite3 binary not found!<br><br>CMake Error at CMakeLists.txt:181 (message):<br>  sqlite3 dependency not found!<br><br>CMake Error at CMakeLists.txt:187 (message):<br>  sqlite3 >= 3.11 required!<br><br>CMake Error at C:/Program Files/CMake/share/cmake-3.25/Modules/FindPackageHandleStandardArgs.cmake:230 (message):<br>  Could NOT find TIFF (missing: TIFF_LIBRARY TIFF_INCLUDE_DIR)<br>Call Stack (most recent call first):<br>  C:/Program Files/CMake/share/cmake-3.25/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE)<br>  C:/Program Files/CMake/share/cmake-3.25/Modules/FindTIFF.cmake:124 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)<br>  CMakeLists.txt:198 (find_package)<br><br>-- Configuring incomplete, errors occurred!<br>See also "D:/Downloads/proj-9.1.1/CMakeFiles/CMakeOutput.log".<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">I have copied the sqlite3.exe and .dll from OSGeo4W into both folders, and it still doesn't think sqlite is there. I'll keep going through cmake tutorials to try to understand how I can satisfy it, but any help is appreciated - even better if SharpProj can be made to work. At this point I am a bit sad as I'm in over my head. I can supply a basic project trying to use the OSGeo4W DLLs too, if you'd like to look at that.<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">Thanks so much for reading to this point!<u></u><u></u></p><div><p class="MsoNormal"><u></u> <u></u></p></div><div><div><div><div><table border="0" cellspacing="0" cellpadding="0" style="border-collapse:collapse"><tbody><tr><td style="padding:0cm 0cm 3.75pt"><p class="MsoNormal" style="line-height:13.2pt"><b><span style="font-size:13pt;color:rgb(51,51,51)">Jonathan Johansen</span></b><span style="font-size:12pt;font-family:"inherit",serif;color:rgb(33,37,41)"><u></u><u></u></span></p></td></tr><tr><td style="padding:0cm"><p class="MsoNormal" style="line-height:13.2pt"><span style="font-size:13pt;color:rgb(51,51,51)">M:</span><span style="font-size:12pt;font-family:"inherit",serif;color:rgb(33,37,41)"> <a href="tel:0438922553" target="_blank"><span style="font-size:13pt;font-family:Calibri,sans-serif;color:rgb(0,102,204)">0438 922 553</span></a><u></u><u></u></span></p></td></tr><tr><td style="padding:0cm 0cm 7.5pt"><p class="MsoNormal" style="line-height:13.2pt"><span style="font-size:13pt;color:rgb(51,51,51)">E:</span><span style="font-size:12pt;font-family:"inherit",serif;color:rgb(33,37,41)"> <a href="mailto:jonathan@t3rra.com" target="_blank">jonathan@t3rra.com</a></span><span style="font-size:13pt;color:rgb(90,99,119)"><br></span><span style="font-size:13pt;color:rgb(51,51,51)">W:</span><span style="font-size:12pt;font-family:"inherit",serif;color:rgb(33,37,41)"> <a href="http://www.t3rra.com/" target="_blank">http://www.t3rra.com/</a><u></u><u></u></span></p></td></tr></tbody></table><p class="MsoNormal"><u></u> <u></u></p></div></div></div></div></div></div></div></div>_______________________________________________<br>
PROJ mailing list<br>
<a href="mailto:PROJ@lists.osgeo.org" target="_blank">PROJ@lists.osgeo.org</a><br>
<a href="https://lists.osgeo.org/mailman/listinfo/proj" rel="noreferrer" target="_blank">https://lists.osgeo.org/mailman/listinfo/proj</a><br>
</div></blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>Peter Townsend<br></div>Senior Software Developer<br></div></div>