Unable to find RenderContent in DLL 'rhcommonrdk_c'

Hi All,

I am using Rhino.Inside to run my unit tests and I am not sure why I am getting this error System.EntryPointNotFoundException : Unable to find an entry point named 'Rdk_RenderContent_RdkDocumentRegisteredId' in DLL 'rhcommonrdk_c'. and how I can respond to it.

The error happens in the second test PurgeMaterials_WhenCalledWithDifferentNumberOfRenderMaterials_ReturnsSpecificString and at the line where I am creating renderMaterial

This is how my unit test project is setup
image
I have only two modules in this project:

  1. TestSetup
  2. Tests

Here’s my TestSetup

using Microsoft.Win32;
using System;
using System.IO;
using NUnit.Framework;

namespace Space.UnitTests
{
    [SetUpFixture]
    public class SetupFixture
    {
        private bool _initialized;
        private static string _rhinoDir = "";
        private Rhino.Runtime.InProcess.RhinoCore? _rhinoCore;

        [OneTimeSetUp]
        public void Initialize()
        {
            //get the correct rhino 7 installation directory
            _rhinoDir = Registry.GetValue(
                @"HKEY_LOCAL_MACHINE\SOFTWARE\McNeel\Rhinoceros\7.0\Install",
                "Path",
                null) as string ?? string.Empty;
            Assert.IsTrue(Directory.Exists(_rhinoDir), $"Rhino system dir not found: {_rhinoDir}");

            // Make sure we are running the tests as 64x
            Assert.IsTrue(Environment.Is64BitProcess, "Tests must be run as x64");

            if (_initialized)
            {
                throw new InvalidOperationException("Initialize Rhino.Inside once");
            }

            RhinoInside.Resolver.Initialize();
            _initialized = true;
            
            // Set path to rhino system directory
            string envPath = Environment.GetEnvironmentVariable("path")?? String.Empty ;
            Environment.SetEnvironmentVariable("path", envPath + ";" + _rhinoDir);

            StartRhino();
        }

        /// <summary>
        /// Start a headless Rhino instance using Rhino.Inside
        /// </summary>
        public void StartRhino()
        {
            _rhinoCore = new Rhino.Runtime.InProcess.RhinoCore(null, 
                Rhino.Runtime.InProcess.WindowStyle.NoWindow);
        }

        [OneTimeTearDown]
        public void Cleanup()
        {
            _rhinoCore?.Dispose();
            _rhinoCore = null;
        }
    }
}

And here’s my tests

using Rhino;
using NUnit.Framework;
using Rhino.DocObjects;
using Rhino.Render;
using Space.Commands;
using Rhino.Geometry;
using Rhino.UI;

namespace Space.UnitTests
{
    [TestFixture]
    public class SpacePurgeMaterialsTests
    {
        private RhinoDoc? _doc;

        [SetUp]
        public void Setup()
        {
            _doc = RhinoDoc.CreateHeadless(null);
        }

        [TestCase(0, "No materials found in this file to purge.")]
        [TestCase(1, "Purged 1 material from the file.")]
        [TestCase(2, "Purged 2 materials from the file.")]
        public void PurgeMaterials_WhenCalledWithDifferentNumberOfMaterials_ReturnsSpecificString(
            int materialCount, string expected)
        {
            // Arrange
            for (int i = 0; i < materialCount; i++)
            {
                _doc?.Materials.Add();
            }

            // Act
            string result = SpacePurgeMaterials.PurgeMaterials(_doc);

            // Assert
            Assert.AreEqual(expected, result);
        }

        [Test]
        public void PurgeMaterials_WhenCalledWithDifferentNumberOfRenderMaterials_ReturnsSpecificString()
        {
            // Arrange
            // Create a new material
            var rhinoMaterial = new Material();

            // Use the Rhino material to create a Render material
            var renderMaterial = RenderMaterial.CreateBasicMaterial(rhinoMaterial, _doc);
            _doc.RenderMaterials.Add(renderMaterial);

            // Create a box
            var box = new Box(Plane.WorldXY, new Interval(-5, 5), new Interval(-5, 5), new Interval(-5, 5));
            var id = _doc.Objects.AddBox(box);

            // Assign the render material to the box object
            var obj = _doc.Objects.FindId(id);
            if (obj != null)
            {
                obj.RenderMaterial = renderMaterial;
                obj.CommitChanges();
            }
            string expected = "Purged 1 material from the file.";

            // Act
            string result = SpacePurgeMaterials.PurgeMaterials(_doc);

            // Assert
            Assert.AreEqual(expected, result);
        }



        [TearDown]
        public void TearDown()
        {
            _doc?.Dispose();
    
        }
    }
}

@oguzhankoral any thoughts?

@Alain any thoughts?

If you stick a breakpoint in SetUpFixture.Initialize does it get hit?

Thanks for looking into this @csykes , I am not quite sure where you want me to insert the breakpoint. Can you point me on the code I shared?

I inserted a breakpoint at _rhinoDir in Initialize(). If I run my test in debug mode, the breakpoint gets hit.

1 Like

Smashing, and if you walk through that method does it make it all the way to the end?
I’m also going to assume you have Rhino 7 installed and it is licensed? :slight_smile:

Yes. It reaches all the way to the end of Initialize. And yes, I have Rhino 7 licensed

@Devang_Chauhan

Try loading your Rhino core like this:

s_core = new Rhino.Runtime.InProcess.RhinoCore(args);

// NOTE:
// ensure RDK and its associated native libraries are ready
// rdk.rhp plugin must be loaded before the rdk native library.
// a fresh build of rhino on builder machines does not load this
string rdkRhp = Path.Combine(Configs.Current.RhinoSystemDir, "Plug-ins", "rdk.rhp");
Rhino.PlugIns.PlugIn.LoadPlugIn(rdkRhp, out Guid _);

Rhino.Runtime.HostUtils.InitializeRhinoCommon_RDK();

Try using the Rhino.Testing library. Example project is here:

2 Likes

Thank you @eirannejad! Great to see McNeel creating the testing library and a sample project. That was helpful. I was able to use the sample project to successfully run my tests. I however, have the following plugin error pop-up before the tests run.

image

Here’s how my csproj looks

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
	  <langversion>10.0</langversion>
	  <RhinoSystemDirectory>C:\Program Files\Rhino 7\System</RhinoSystemDirectory>
  </PropertyGroup>

  <ItemGroup>
	  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.*" />
	  <PackageReference Include="NUnit" Version="3.14" />
	  <PackageReference Include="NUnit3TestAdapter" Version="4.5" />
	  <PackageReference Include="Rhino.Testing" Version="8.0.6-beta" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\WombatRhino\WombatRhino.csproj" />
  </ItemGroup>

	<ItemGroup Condition=" $(TargetFramework.Contains('net48')) == 'true'">
		<Reference Include="$(RhinoSystemDirectory)\RhinoCommon.dll" Private="False" />
	</ItemGroup>

	<ItemGroup>
		<None Update="Rhino.Testing.Configs.xml" CopyToOutputDirectory="always" />
		<None Update="Files\circle.3dm" CopyToOutputDirectory="PreserveNewest" />
		<None Update="Files\circle.gh" CopyToOutputDirectory="PreserveNewest" />
	</ItemGroup>

</Project>

Here’s my Rhino.Testing.Configs.xml

<?xml version="1.0" encoding="utf-8"?>
<Settings>
	<RhinoSystemDirectory>C:\Program Files\Rhino 7\System</RhinoSystemDirectory>
</Settings>

Ok I saw that. I’m working on it right now and will update here.

May be don’t. I started with a blank slate and re-setup my project and now I don’t see Uable to load rdk.rhp plugin-in; initialization failed.

I just published 8.0.9-beta and it does not load RDK by default.

If you wanted Grasshopper to load you have to add <LoadGrasshopper>true</LoadGrasshopper> to the config file

See updated README

Thank you @csykes and @eirannejad for taking a look.

2 Likes