Update C Plugin to 2024 issue

I have a c based plugin that I originally wrote for Sketchup 2019, and have updated each year to support 2020, 2021, 2022 and 2023.

I have attempted to update it to 2024, but struggling.

I am using the new 2024 SDK, and Ruby 3.2.2 (as copied from SDK folder samples\common\ThirdParty\ruby), and building in Visual Studio 2019.

The plugin folder structure is identical to what have use in the past.

Still when I try to call a function in my 2024 .so file, I get

Error: #<LoadError: 127: The specified procedure could not be found.   - C:/Users/mgraham/AppData/Roaming/SketchUp/SketchUp 2024/SketchUp/Plugins/su_myPlugin/bin64/myOmniPlugin.so>
C:/Users/mgraham/AppData/Roaming/SketchUp/SketchUp 2024/SketchUp/Plugins/su_myOmniPlugin/loader.rb:34:in `require_relative'
C:/Users/mgraham/AppData/Roaming/SketchUp/SketchUp 2024/SketchUp/Plugins/su_myPlugin/loader.rb:34:in `execute'
C:/Users/mgraham/AppData/Roaming/SketchUp/SketchUp 2024/SketchUp/Plugins/su_myPlugin/loader.rb:161:in `block in <module:mycode>'

The identical source code built with 2023 SDK and Ruby 2.7.0 works correctly in Sketchup 2023.

Are there other update steps that I missed?

1 Like

Tip: check that you are not using something deprecated in your Ruby code that was removed in R3.2+ In my case I used File.exists? which was removed in R3.2 so I also had a similar issue.

NOTE: Bracketed italicized inserts and emboldening by me for clarity.


The C API introduction page says …

The [ current 2024 ] C API library for Windows is built using Microsoft Visual Studio 2022 (v143).

… and …

SketchUp 2020, 2021, 2022, and 2023.0 for Windows were built using Visual Studio 2019, and so plugins [ for these versions ] should be built with the Platform Toolset set to Visual Studio 2019 (v142).

… further …

Using a different Platform Toolset will likely cause the plugin to fail to load and cause SketchUp to crash.

So, this implies you should be compiling to the VS v143 Toolset for SketchUp 2024 C extensions.


Also …

Between Ruby 2.7 and Ruby 3.2, the name of the DLL produced by the Windows Ruby installer
changed to: x64-ucrt-ruby320.dll.

While we [ Trimble SketchUp ] can’t officially support binaries built against anything other than the headers/libs we provide, we changed our DLL name to match.

Thanks, I will try vs2022. I did update the ruby dll name. Will report back on my results.

1 Like

Updated to vs2022 and toolset v143. Rebuilt and tested with both my 2023 and 2024 version of my plugin. The 2023 version works, the 2024 version is still giving me the same error as above.

I don’t recall seeing that error previously. I made some PR’s/commits that updated c source to work in Ruby 3.x for a couple of popular extension gems, but that error wasn’t mentioned. They’re from several years ago (2020?), so I’m a bit foggy as to the reasons. Also, I’ve never compiled code for use with SketchUp.

I’m surprised you aren’t seeing any errors when you compile the file. Feel free to PM me if you want another set of eyes on your code. I’m more a Ruby coder than a C coder…

All my ruby code seems fine. It is creating my toolbar, and printing my variables is working. It is my calls to my c code that is causing errors.

This issue is about your c source. I wasn’t referring to Ruby code.

The error text your showed above implies that your *.so file isn’t loading (LoadError on require_relative). Obviously, calls to it won’t work if it’s not loading.

myLoader.rb (1.3 KB)
I have attached my ruby file. I have comment out the lines that do not work.
My toolbar appears
If line 7 is commented out, when I click each of the buttons, it shows the message in the ruby console.
As soon as I uncomment line 7, I get the require_relative error

This Ruby file does not show the problem. It is on the C-side.

And since it works for 2023 and Ruby 2.7 and not 2024 and Ruby 3.2 the issue is with versioning.

Are you sure that the version of Ruby being used for the 2024 edition is Ruby 3.2.2 ?

Generally, you cannot load the same compiled so into SU versions using Ruby 2.7 and Ruby 3.2.
You need to compile two editions and use a conditional expression in Ruby to load the correct one for what SU version the user is running.

case RUBY_VERSION.to_f
when 2.7
  require_relative 'bin64/2.7/myPlugin.so'
when 3.2
  require_relative 'bin64/3.2/myPlugin.so'
end

We create total separate folders for the 2023 files and 2024 files.
Do we need to copy x64-ucrt-ruby320.dll with our other support dlls?

I do not think so if you are running a Live C extension, since SketchUp has already loaded it.

Ok, will look more deeply into any missing support dlls on my side

Is your c code using any other dll’s that aren’t standard Windows files or x64-ucrt-ruby320.dll ?

Yes we have additional dlls. The odd thing is that we create the same set of support dlls for both our 2024 and 2023 installs, and the 2023 works but 2024 does not

These are dll’s that you compile? Where do you locate them? How are they loaded?

Or, I’ve never seen code that included dll’s and didn’t need to load them. One of the ‘database’ gems does something similar.

So, this may be due to a change in how SU handles $LOAD_PATH, not sure.

To set the paths to load our extra dlls, we have been doing the following in myLoader.rb (I left this part out of the file I sent previously). This has worked for all past versions of our plugin

#Get the environment path
orgPath = ENV['Path']
#Get the support path to add, based on Sketchup version
skPath = ENV['APPDATA'] + "\\SketchUp\\"
skVersion = ""

if (2300000000...2399999999) === Sketchup.version_number
  skVersion += "SketchUp 2023"
end
if (2400000000...2499999999) === Sketchup.version_number
  skVersion += "SketchUp 2024"
end

skPath += skVersion + "\\SketchUp\\Plugins\\su_myPlugin\\libsupport;"
#Add the support path to the beginning of the environment path list (in session only)
ENV['Path'] = skPath + orgPath

How about:

plugins = Sketchup.find_support_file("Plugins")
#=> "C:/Users/Dan/AppData/Roaming/SketchUp/SketchUp 2024/SketchUp/Plugins"

then …

skPath = File.join(plugins, 'su_myPlugin/libsupport')
ENV["Path"]= "#{ENV["Path"]};#{skPath}"

?


Also, if the file being evaluated is already within your extension subfolder, you can simply use the global __dir__ method, ie:

libPath = File.join(__dir__, 'libsupport')

NOTE: This is likely safer than assuming the plugin will be in the %AppData% “Plugins” path.
Some users move extensions into the %ProgramData% “Plugins” folder OR into some folder on another drive entirely (and use a load shim file in “Plugins” or an extension like Fredo’s AdditionalPluginsPath extension to point SketchUp to some alternate user “Plugins” directory.)

To verify that loading the dll’s isn’t a problem, try copying them to the below, which is already in ENV['Path']

C:/Program Files/SketchUp/SketchUp 2024/Tools/RubyStdLib/platform_specific

and see if your code loads. Obviously, remove them after you test loading…

Ands, what Dan said, using __dir__ is quite a bit shorter…

We have an installer that builds the all the folder paths for the plugin. I have add a “puts” statement to my loader.rb to show what the paths are, and they are correct. My current theory is there is a support file unique to 2024 that is not being copied.